diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d3d52e048be..f06f73e4025 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -176,7 +176,7 @@ jobs: strategy: fail-fast: false matrix: - apps: [reactrouter5] + apps: [reactrouter6] needs: [build-react, build-react-router] runs-on: ubuntu-latest steps: diff --git a/.github/workflows/stencil-nightly.yml b/.github/workflows/stencil-nightly.yml index b00ac8c42a0..1f56207fa1c 100644 --- a/.github/workflows/stencil-nightly.yml +++ b/.github/workflows/stencil-nightly.yml @@ -186,7 +186,7 @@ jobs: strategy: fail-fast: false matrix: - apps: [reactrouter5] + apps: [reactrouter6] needs: [build-react, build-react-router] runs-on: ubuntu-latest steps: diff --git a/BREAKING.md b/BREAKING.md index bf44f563dc8..8e977147746 100644 --- a/BREAKING.md +++ b/BREAKING.md @@ -4,6 +4,7 @@ This is a comprehensive list of the breaking changes introduced in the major ver ## Versions +- [Version 9.x](#version-9x) - [Version 8.x](#version-8x) - [Version 7.x](./BREAKING_ARCHIVE/v7.md) - [Version 6.x](./BREAKING_ARCHIVE/v6.md) @@ -11,6 +12,68 @@ This is a comprehensive list of the breaking changes introduced in the major ver - [Version 4.x](./BREAKING_ARCHIVE/v4.md) - [Legacy](https://github.com/ionic-team/ionic-v3/blob/master/CHANGELOG.md) +## Version 9.x + +- [Framework Specific](#version-9x-framework-specific) + - [React](#version-9x-react) + +

Framework Specific

+ +

React

+ +The `@ionic/react-router` package now requires React Router v6. React Router v5 is no longer supported. + +**Minimum Version Requirements** +| Package | Supported Version | +| ---------------- | ----------------- | +| react-router | 6.0.0+ | +| react-router-dom | 6.0.0+ | + +React Router v6 introduces several API changes that will require updates to your application's routing configuration: + +**Route Definition Changes** + +The `component` prop has been replaced with the `element` prop, which accepts JSX: + +```diff +- ++ } /> +``` + +**Redirect Changes** + +The `` component has been replaced with ``: + +```diff +- import { Redirect } from 'react-router-dom'; ++ import { Navigate } from 'react-router-dom'; + +- ++ +``` + +**Nested Route Paths** + +Routes that contain nested routes or child `IonRouterOutlet` components need a `/*` suffix to match sub-paths: + +```diff +- } /> ++ } /> +``` + +**Accessing Route Parameters** + +Route parameters are now accessed via the `useParams` hook instead of props: + +```diff +- const MyComponent: React.FC> = ({ match }) => { +- const id = match.params.id; ++ const MyComponent: React.FC = () => { ++ const { id } = useParams<{ id: string }>(); +``` + +For more information on migrating from React Router v5 to v6, refer to the [React Router v6 Upgrade Guide](https://reactrouter.com/en/main/upgrading/v5). + ## Version 8.x - [Browser and Platform Support](#version-8x-browser-platform-support) diff --git a/package-lock.json b/package-lock.json index d071e527ba9..54ec41085ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9288,8 +9288,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "dev": true, - "requires": {} + "dev": true }, "@octokit/plugin-rest-endpoint-methods": { "version": "6.6.2", diff --git a/packages/react-router/package-lock.json b/packages/react-router/package-lock.json index 56b884f97c4..81dedf1a101 100644 --- a/packages/react-router/package-lock.json +++ b/packages/react-router/package-lock.json @@ -1,7 +1,7 @@ { "name": "@ionic/react-router", "version": "8.7.12", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -19,16 +19,15 @@ "@types/node": "^14.0.14", "@types/react": "^17.0.79", "@types/react-dom": "^17.0.25", - "@types/react-router": "^5.0.3", - "@types/react-router-dom": "^5.1.5", "@typescript-eslint/eslint-plugin": "^5.48.2", "@typescript-eslint/parser": "^5.48.2", "eslint": "^7.32.0", + "history": "^5.3.0", "prettier": "^2.8.3", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-router": "^5.0.1", - "react-router-dom": "^5.0.1", + "react-router": "^6.30.0", + "react-router-dom": "^6.30.0", "rimraf": "^3.0.2", "rollup": "^4.2.0", "typescript": "^4.0.5" @@ -36,17 +35,8 @@ "peerDependencies": { "react": ">=16.8.6", "react-dom": ">=16.8.6", - "react-router": "^5.0.1", - "react-router-dom": "^5.0.1" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "react-router": ">=6.0.0", + "react-router-dom": ">=6.0.0" } }, "node_modules/@babel/code-frame": { @@ -54,28 +44,32 @@ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/highlight": "^7.10.4" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", + "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.25.9", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -86,6 +80,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -98,6 +93,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -112,6 +108,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -120,13 +117,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -136,6 +135,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -145,6 +145,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -153,37 +154,40 @@ } }, "node_modules/@babel/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -193,6 +197,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -213,6 +218,7 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -221,7 +227,9 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", @@ -235,7 +243,9 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@ionic/core": { "version": "8.7.12", @@ -256,6 +266,7 @@ "resolved": "https://registry.npmjs.org/@ionic/eslint-config/-/eslint-config-0.3.0.tgz", "integrity": "sha512-Uf1hS2YIoHlcvXPF5LnsPM6auMewEdChQhR117Rt3sVEAutbyKMpFP4slNC2a6up3a5Q34zepqlf61Qgkf9XeQ==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/eslint-plugin": "^4.1.0", "@typescript-eslint/parser": "^4.1.0", @@ -271,6 +282,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/experimental-utils": "4.33.0", "@typescript-eslint/scope-manager": "4.33.0", @@ -303,6 +315,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "dev": true, + "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "4.33.0", "@typescript-eslint/types": "4.33.0", @@ -330,6 +344,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0" @@ -347,6 +362,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true, + "license": "MIT", "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, @@ -360,6 +376,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0", @@ -387,6 +404,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "4.33.0", "eslint-visitor-keys": "^2.0.0" @@ -404,6 +422,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10" } @@ -413,6 +432,7 @@ "resolved": "https://registry.npmjs.org/@ionic/prettier-config/-/prettier-config-2.1.2.tgz", "integrity": "sha512-lpjXnu5XmzxDrHinjGa9z/bNe7KgXaehk6NyasyXqwzvE9EyhOSdSrkw6wS2q0HRyw8+x1GZNs2JDJ5cYq39Jw==", "dev": true, + "license": "MIT", "peerDependencies": { "prettier": "^2.4.0" } @@ -437,6 +457,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -450,6 +471,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -459,6 +481,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -467,13 +490,24 @@ "node": ">= 8" } }, + "node_modules/@remix-run/router": { + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.1.tgz", + "integrity": "sha512-vDbaOzF7yT2Qs4vO6XV1MHcJv+3dgR1sT+l3B8xxOVhUC336prMvqrvsLL/9Dnw2xr6Qhz4J0dmS0llNAbnUmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-typescript": { - "version": "11.1.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz", - "integrity": "sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==", + "version": "11.1.6", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz", + "integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==", "dev": true, + "license": "MIT", "dependencies": { - "@rollup/pluginutils": "^5.0.1", + "@rollup/pluginutils": "^5.1.0", "resolve": "^1.22.1" }, "engines": { @@ -494,14 +528,15 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz", - "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" + "picomatch": "^4.0.2" }, "engines": { "node": ">=14.0.0" @@ -516,237 +551,212 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.3.0.tgz", - "integrity": "sha512-/4pns6BYi8MXdwnXM44yoGAcFYVHL/BYlB2q1HXZ6AzH++LaiEVWFpBWQ/glXhbMbv3E3o09igrHFbP/snhAvA==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", + "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.3.0.tgz", - "integrity": "sha512-nLO/JsL9idr416vzi3lHm3Xm+QZh4qHij8k3Er13kZr5YhL7/+kBAx84kDmPc7HMexLmwisjDCeDIKNFp8mDlQ==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", + "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.3.0.tgz", - "integrity": "sha512-dGhVBlllt4iHwTGy21IEoMOTN5wZoid19zEIxsdY29xcEiOEHqzDa7Sqrkh5OE7LKCowL61eFJXxYe/+pYa7ZQ==", + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz", + "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==", "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.3.0.tgz", - "integrity": "sha512-h8wRfHeLEbU3NzaP1Oku7BYXCJQiTRr+8U0lklyOQXxXiEpHLL8tk1hFl+tezoRKLcPJD7joKaK74ASsqt3Ekg==", + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz", + "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==", "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.3.0.tgz", - "integrity": "sha512-wP4VgR/gfV18sylTuym3sxRTkAgUR2vh6YLeX/GEznk5jCYcYSlx585XlcUcl0c8UffIZlRJ09raWSX3JDb4GA==", + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", + "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", "cpu": [ - "arm" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "linux" + "freebsd" ] }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.3.0.tgz", - "integrity": "sha512-v/14JCYVkqRSJeQbxFx4oUkwVQQw6lFMN7bd4vuARBc3X2lmomkxBsc+BFiIDL/BK+CTx5AOh/k9XmqDnKWRVg==", + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", + "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", "cpu": [ - "arm64" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "linux" + "freebsd" ] }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.3.0.tgz", - "integrity": "sha512-tNhfYqFH5OxtRzfkTOKdgFYlPSZnlDLNW4+leNEvQZhwTJxoTwsZAAhR97l3qVry/kkLyJPBK+Q8EAJLPinDIg==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", + "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", "cpu": [ - "arm64" + "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.3.0.tgz", - "integrity": "sha512-pw77m8QywdsoFdFOgmc8roF1inBI0rciqzO8ffRUgLoq7+ee9o5eFqtEcS6hHOOplgifAUUisP8cAnwl9nUYPw==", + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", + "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", "cpu": [ - "x64" + "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.3.0.tgz", - "integrity": "sha512-tJs7v2MnV2F8w6X1UpPHl/43OfxjUy9SuJ2ZPoxn79v9vYteChVYO/ueLHCpRMmyTUIVML3N9z4azl9ENH8Xxg==", + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz", + "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==", "cpu": [ - "x64" + "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.3.0.tgz", - "integrity": "sha512-OKGxp6kATQdTyI2DF+e9s+hB3/QZB45b6e+dzcfW1SUqiF6CviWyevhmT4USsMEdP3mlpC9zxLz3Oh+WaTMOSw==", + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz", + "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==", "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ] }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.3.0.tgz", - "integrity": "sha512-DDZ5AH68JJ2ClQFEA1aNnfA7Ybqyeh0644rGbrLOdNehTmzfICHiWSn0OprzYi9HAshTPQvlwrM+bi2kuaIOjQ==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", + "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", "cpu": [ - "ia32" + "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ] }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.3.0.tgz", - "integrity": "sha512-dMvGV8p92GQ8jhNlGIKpyhVZPzJlT258pPrM5q2F8lKcc9Iv9BbfdnhX1OfinYWnb9ms5zLw6MlaMnqLfUkKnQ==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", + "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", "cpu": [ - "x64" + "ppc64" ], "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@stencil/core": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.38.0.tgz", - "integrity": "sha512-oC3QFKO0X1yXVvETgc8OLY525MNKhn9vISBrbtKnGoPlokJ6rI8Vk1RK22TevnNrHLI4SExNLbcDnqilKR35JQ==", - "license": "MIT", - "bin": { - "stencil": "bin/stencil" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.10.0" - }, - "optionalDependencies": { - "@rollup/rollup-darwin-arm64": "4.34.9", - "@rollup/rollup-darwin-x64": "4.34.9", - "@rollup/rollup-linux-arm64-gnu": "4.34.9", - "@rollup/rollup-linux-arm64-musl": "4.34.9", - "@rollup/rollup-linux-x64-gnu": "4.34.9", - "@rollup/rollup-linux-x64-musl": "4.34.9", - "@rollup/rollup-win32-arm64-msvc": "4.34.9", - "@rollup/rollup-win32-x64-msvc": "4.34.9" - } - }, - "node_modules/@stencil/core/node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz", - "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==", - "cpu": [ - "arm64" - ], "license": "MIT", "optional": true, "os": [ - "darwin" + "linux" ] }, - "node_modules/@stencil/core/node_modules/@rollup/rollup-darwin-x64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz", - "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==", + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", + "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", "cpu": [ - "x64" + "riscv64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "darwin" + "linux" ] }, - "node_modules/@stencil/core/node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz", - "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==", + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", + "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", "cpu": [ - "arm64" + "riscv64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@stencil/core/node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz", - "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==", + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", + "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", "cpu": [ - "arm64" + "s390x" ], + "dev": true, "license": "MIT", "optional": true, "os": [ "linux" ] }, - "node_modules/@stencil/core/node_modules/@rollup/rollup-linux-x64-gnu": { + "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.34.9", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz", "integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==", @@ -759,7 +769,7 @@ "linux" ] }, - "node_modules/@stencil/core/node_modules/@rollup/rollup-linux-x64-musl": { + "node_modules/@rollup/rollup-linux-x64-musl": { "version": "4.34.9", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz", "integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==", @@ -772,7 +782,21 @@ "linux" ] }, - "node_modules/@stencil/core/node_modules/@rollup/rollup-win32-arm64-msvc": { + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", + "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { "version": "4.34.9", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz", "integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==", @@ -785,7 +809,35 @@ "win32" ] }, - "node_modules/@stencil/core/node_modules/@rollup/rollup-win32-x64-msvc": { + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", + "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", + "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.34.9", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz", "integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==", @@ -798,100 +850,114 @@ "win32" ] }, - "node_modules/@types/estree": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.4.tgz", - "integrity": "sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw==", - "dev": true + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@stencil/core": { + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.38.0.tgz", + "integrity": "sha512-oC3QFKO0X1yXVvETgc8OLY525MNKhn9vISBrbtKnGoPlokJ6rI8Vk1RK22TevnNrHLI4SExNLbcDnqilKR35JQ==", + "license": "MIT", + "bin": { + "stencil": "bin/stencil" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.10.0" + }, + "optionalDependencies": { + "@rollup/rollup-darwin-arm64": "4.34.9", + "@rollup/rollup-darwin-x64": "4.34.9", + "@rollup/rollup-linux-arm64-gnu": "4.34.9", + "@rollup/rollup-linux-arm64-musl": "4.34.9", + "@rollup/rollup-linux-x64-gnu": "4.34.9", + "@rollup/rollup-linux-x64-musl": "4.34.9", + "@rollup/rollup-win32-arm64-msvc": "4.34.9", + "@rollup/rollup-win32-x64-msvc": "4.34.9" + } }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", - "dev": true + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" }, "node_modules/@types/json-schema": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", - "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "14.18.63", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/prop-types": { - "version": "15.7.9", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.9.tgz", - "integrity": "sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==", - "dev": true + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/react": { - "version": "17.0.79", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.79.tgz", - "integrity": "sha512-gavKA8AwJAML9zWHuiQRASjrrPJHbT/zrUDHiUGUf+l5a3pkEd6atvjjq+8y2vfRHBJLQJjFpxSa9I8qe9zHAw==", + "version": "17.0.90", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.90.tgz", + "integrity": "sha512-P9beVR/x06U9rCJzSxtENnOr4BrbJ6VrsrDTc+73TtHv9XHhryXKbjGRB+6oooB2r0G/pQkD/S4dHo/7jUfwFw==", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" + "@types/scheduler": "^0.16", + "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { - "version": "17.0.25", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.25.tgz", - "integrity": "sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA==", - "dev": true, - "dependencies": { - "@types/react": "^17" - } - }, - "node_modules/@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "dev": true, - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "version": "17.0.26", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.26.tgz", + "integrity": "sha512-Z+2VcYXJwOqQ79HreLU/1fyQ88eXSSFh6I3JdrEHQIfYSI0kCQpTGvOrbE6jFGGYXKsHuwY9tBa/w5Uo6KzrEg==", "dev": true, - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0" } }, "node_modules/@types/scheduler": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", - "dev": true + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.62.0", @@ -926,6 +992,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.7", "@typescript-eslint/scope-manager": "4.33.0", @@ -950,6 +1017,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0" @@ -967,6 +1035,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true, + "license": "MIT", "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, @@ -980,6 +1049,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0", @@ -1007,6 +1077,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "4.33.0", "eslint-visitor-keys": "^2.0.0" @@ -1024,6 +1095,7 @@ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^2.0.0" }, @@ -1042,6 +1114,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10" } @@ -1051,6 +1124,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, + "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -1078,6 +1153,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0" @@ -1095,6 +1171,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "5.62.0", "@typescript-eslint/utils": "5.62.0", @@ -1122,6 +1199,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -1135,6 +1213,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "5.62.0", "@typescript-eslint/visitor-keys": "5.62.0", @@ -1162,6 +1241,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", @@ -1188,6 +1268,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" @@ -1205,6 +1286,8 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, + "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1217,6 +1300,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -1226,6 +1310,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1242,6 +1327,7 @@ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1251,6 +1337,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1260,6 +1347,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -1275,34 +1363,43 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-string": "^1.0.7" + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -1316,21 +1413,25 @@ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -1340,15 +1441,16 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -1358,15 +1460,16 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -1376,18 +1479,19 @@ } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, + "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -1401,15 +1505,30 @@ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -1421,39 +1540,78 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "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==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "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==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, + "license": "MIT", "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1464,6 +1622,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1473,6 +1632,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -1489,6 +1649,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -1500,19 +1661,22 @@ "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 + "dev": true, + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" }, "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==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1523,18 +1687,74 @@ } }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "dev": true + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1549,20 +1769,25 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-properties": { @@ -1570,6 +1795,7 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -1587,6 +1813,7 @@ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -1599,6 +1826,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -1606,17 +1834,34 @@ "node": ">=6.0.0" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "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 + "dev": true, + "license": "MIT" }, "node_modules/enquirer": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -1626,50 +1871,66 @@ } }, "node_modules/es-abstract": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", - "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "dev": true, + "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.5", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.2", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.12", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.13" + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" }, "engines": { "node": ">= 0.4" @@ -1678,38 +1939,78 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, + "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -1723,6 +2024,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -1734,7 +2036,10 @@ "version": "7.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -1792,6 +2097,7 @@ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", "dev": true, + "license": "MIT", "dependencies": { "get-stdin": "^6.0.0" }, @@ -1807,6 +2113,7 @@ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -1818,15 +2125,17 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^3.2.7" }, @@ -1844,39 +2153,43 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", - "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, + "license": "MIT", "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, "node_modules/eslint-plugin-import/node_modules/debug": { @@ -1884,6 +2197,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } @@ -1893,6 +2207,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -1905,6 +2220,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -1914,6 +2230,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -1927,6 +2244,7 @@ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^1.1.0" }, @@ -1942,6 +2260,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=4" } @@ -1951,6 +2270,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -1963,6 +2283,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10" } @@ -1972,6 +2293,7 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -1981,6 +2303,7 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", @@ -1995,6 +2318,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=4" } @@ -2004,6 +2328,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -2013,10 +2338,11 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -2029,6 +2355,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2038,6 +2365,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -2050,6 +2378,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2059,6 +2388,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2067,13 +2397,15 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -2082,19 +2414,21 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -2104,19 +2438,39 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -2126,6 +2480,7 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -2134,10 +2489,11 @@ } }, "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==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2146,39 +2502,49 @@ } }, "node_modules/flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { - "node": ">=12.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" }, "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, + "license": "MIT", "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "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 + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", @@ -2186,6 +2552,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -2199,20 +2566,24 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -2225,49 +2596,88 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -2280,7 +2690,9 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2301,6 +2713,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2309,10 +2722,11 @@ } }, "node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -2324,12 +2738,14 @@ } }, "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, + "license": "MIT", "dependencies": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -2343,6 +2759,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -2359,12 +2776,13 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2374,13 +2792,18 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2390,27 +2813,33 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -2419,10 +2848,11 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2431,12 +2861,13 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, + "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -2446,10 +2877,11 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -2458,42 +2890,31 @@ } }, "node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", "dev": true, + "license": "MIT", "dependencies": { - "react-is": "^16.7.0" + "@babel/runtime": "^7.7.6" } }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -2510,6 +2931,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -2518,7 +2940,9 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -2528,17 +2952,19 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/internal-slot": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", - "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.2", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -2554,39 +2980,68 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2600,6 +3055,7 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2608,24 +3064,48 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2639,24 +3119,63 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "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, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -2664,11 +3183,25 @@ "node": ">=0.10.0" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2681,17 +3214,20 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2701,14 +3237,30 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2717,24 +3269,30 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2744,12 +3302,15 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, + "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -2759,13 +3320,27 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, + "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.11" + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2774,39 +3349,64 @@ } }, "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "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==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" }, "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==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -2819,25 +3419,29 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.0" }, @@ -2850,6 +3454,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -2859,6 +3464,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -2871,18 +3477,21 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -2890,16 +3499,14 @@ "loose-envify": "cli.js" } }, - "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==", + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">= 0.4" } }, "node_modules/merge2": { @@ -2907,28 +3514,44 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "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, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2941,41 +3564,50 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "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 + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" }, "node_modules/natural-compare-lite": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2985,19 +3617,23 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -3008,14 +3644,16 @@ } }, "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -3025,26 +3663,31 @@ } }, "node_modules/object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -3058,32 +3701,53 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -3096,6 +3760,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3105,6 +3770,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3113,43 +3779,55 @@ "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/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "dev": true, - "dependencies": { - "isarray": "0.0.1" - } + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -3159,6 +3837,8 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, + "license": "MIT", + "peer": true, "bin": { "prettier": "bin-prettier.js" }, @@ -3174,26 +3854,17 @@ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3216,12 +3887,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -3234,6 +3908,8 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -3243,65 +3919,76 @@ "react": "17.0.2" } }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, "node_modules/react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "version": "6.30.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.2.tgz", + "integrity": "sha512-H2Bm38Zu1bm8KUE5NVWRMzuIyAV8p/JrOaBJAwVmp37AXG72+CZJlEBw6pdn9i5TBgLMhNDgijS4ZlblpHyWTA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "@remix-run/router": "1.23.1" + }, + "engines": { + "node": ">=14.0.0" }, "peerDependencies": { - "react": ">=15" + "react": ">=16.8" } }, "node_modules/react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "version": "6.30.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.2.tgz", + "integrity": "sha512-l2OwHn3UUnEVUqc6/1VMmR1cvZryZ3j3NzapC2eUXO1dB0sYp5mvwdjiXhpUbRb21eFow3qSxpP8Yv6oAU824Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "@remix-run/router": "1.23.1", + "react-router": "6.30.2" + }, + "engines": { + "node": ">=14.0.0" }, "peerDependencies": { - "react": ">=15" + "react": ">=16.8", + "react-dom": ">=16.8" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", - "dev": true + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -3315,6 +4002,7 @@ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -3327,23 +4015,28 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3353,21 +4046,17 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", - "dev": true - }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -3377,7 +4066,9 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -3389,10 +4080,15 @@ } }, "node_modules/rollup": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.3.0.tgz", - "integrity": "sha512-scIi1NrKLDIYSPK66jjECtII7vIgdAMFmFo8h6qm++I6nN9qDSV35Ku6erzGVqYjx+lj+j5wkusRMr++8SyDZg==", + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", + "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "1.0.8" + }, "bin": { "rollup": "dist/bin/rollup" }, @@ -3401,21 +4097,143 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.3.0", - "@rollup/rollup-android-arm64": "4.3.0", - "@rollup/rollup-darwin-arm64": "4.3.0", - "@rollup/rollup-darwin-x64": "4.3.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.3.0", - "@rollup/rollup-linux-arm64-gnu": "4.3.0", - "@rollup/rollup-linux-arm64-musl": "4.3.0", - "@rollup/rollup-linux-x64-gnu": "4.3.0", - "@rollup/rollup-linux-x64-musl": "4.3.0", - "@rollup/rollup-win32-arm64-msvc": "4.3.0", - "@rollup/rollup-win32-ia32-msvc": "4.3.0", - "@rollup/rollup-win32-x64-msvc": "4.3.0", + "@rollup/rollup-android-arm-eabi": "4.53.3", + "@rollup/rollup-android-arm64": "4.53.3", + "@rollup/rollup-darwin-arm64": "4.53.3", + "@rollup/rollup-darwin-x64": "4.53.3", + "@rollup/rollup-freebsd-arm64": "4.53.3", + "@rollup/rollup-freebsd-x64": "4.53.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", + "@rollup/rollup-linux-arm-musleabihf": "4.53.3", + "@rollup/rollup-linux-arm64-gnu": "4.53.3", + "@rollup/rollup-linux-arm64-musl": "4.53.3", + "@rollup/rollup-linux-loong64-gnu": "4.53.3", + "@rollup/rollup-linux-ppc64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-musl": "4.53.3", + "@rollup/rollup-linux-s390x-gnu": "4.53.3", + "@rollup/rollup-linux-x64-gnu": "4.53.3", + "@rollup/rollup-linux-x64-musl": "4.53.3", + "@rollup/rollup-openharmony-arm64": "4.53.3", + "@rollup/rollup-win32-arm64-msvc": "4.53.3", + "@rollup/rollup-win32-ia32-msvc": "4.53.3", + "@rollup/rollup-win32-x64-gnu": "4.53.3", + "@rollup/rollup-win32-x64-msvc": "4.53.3", "fsevents": "~2.3.2" } }, + "node_modules/rollup/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", + "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", + "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", + "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", + "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", + "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", + "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", + "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", + "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -3435,19 +4253,22 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/safe-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -3457,21 +4278,36 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3481,19 +4317,18 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" } }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -3502,29 +4337,49 @@ } }, "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, + "license": "MIT", "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, + "license": "MIT", "dependencies": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -3535,6 +4390,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -3547,19 +4403,82 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3570,6 +4489,7 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3579,6 +4499,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -3595,13 +4516,29 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } }, "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, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -3612,14 +4549,19 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -3629,28 +4571,37 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3661,6 +4612,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -3673,6 +4625,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -3682,6 +4635,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -3694,6 +4648,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -3706,6 +4661,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3714,10 +4670,11 @@ } }, "node_modules/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -3730,15 +4687,16 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -3749,31 +4707,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/tiny-invariant": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", - "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", - "dev": true - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", - "dev": true + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -3782,10 +4731,11 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -3794,15 +4744,17 @@ } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, + "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -3817,13 +4769,15 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -3836,6 +4790,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -3844,29 +4799,32 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -3876,16 +4834,19 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, + "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -3895,14 +4856,21 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3913,6 +4881,8 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, + "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3922,15 +4892,19 @@ } }, "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3941,6 +4915,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -3949,19 +4924,15 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", - "dev": true - }, - "node_modules/value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", - "dev": true + "dev": true, + "license": "MIT" }, "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, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -3973,32 +4944,45 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "dev": true, + "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, + "license": "MIT", "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -4007,2844 +4991,63 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wrappy": { + "node_modules/which-collection": { "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/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - }, - "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, + "license": "MIT", "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/runtime": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", - "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.14.0" - } - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" }, - "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - } - } - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@ionic/core": { - "version": "8.7.12", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.12.tgz", - "integrity": "sha512-+QnytOHsMMDEz45hi/t9AN8ATaWMNZ7jNdx621BGSHi0JkEl1c4NylL3cfYIPJ/78y40ZG5NzprwNiR9sXdswg==", - "requires": { - "@stencil/core": "4.38.0", - "ionicons": "^8.0.13", - "tslib": "^2.1.0" - } - }, - "@ionic/eslint-config": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@ionic/eslint-config/-/eslint-config-0.3.0.tgz", - "integrity": "sha512-Uf1hS2YIoHlcvXPF5LnsPM6auMewEdChQhR117Rt3sVEAutbyKMpFP4slNC2a6up3a5Q34zepqlf61Qgkf9XeQ==", - "dev": true, - "requires": { - "@typescript-eslint/eslint-plugin": "^4.1.0", - "@typescript-eslint/parser": "^4.1.0", - "eslint-config-prettier": "^6.11.0", - "eslint-plugin-import": "^2.22.0" + "engines": { + "node": ">= 0.4" }, - "dependencies": { - "@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - } - }, - "@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "@ionic/prettier-config": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ionic/prettier-config/-/prettier-config-2.1.2.tgz", - "integrity": "sha512-lpjXnu5XmzxDrHinjGa9z/bNe7KgXaehk6NyasyXqwzvE9EyhOSdSrkw6wS2q0HRyw8+x1GZNs2JDJ5cYq39Jw==", - "dev": true, - "requires": {} - }, - "@ionic/react": { - "version": "8.7.12", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.7.12.tgz", - "integrity": "sha512-gNm5L++aiwkwJrUFKhcHUUgjqnj9n03gK7UcoL7Oz+271arzmwF/FNd47G85b6PovwiYQXY2CUBvNJ7Nh4qE/A==", - "requires": { - "@ionic/core": "8.7.12", - "ionicons": "^8.0.13", - "tslib": "*" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "@rollup/plugin-typescript": { - "version": "11.1.5", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz", - "integrity": "sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==", + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "resolve": "^1.22.1" + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "@rollup/pluginutils": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz", - "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==", + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "@rollup/rollup-android-arm-eabi": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.3.0.tgz", - "integrity": "sha512-/4pns6BYi8MXdwnXM44yoGAcFYVHL/BYlB2q1HXZ6AzH++LaiEVWFpBWQ/glXhbMbv3E3o09igrHFbP/snhAvA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-android-arm64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.3.0.tgz", - "integrity": "sha512-nLO/JsL9idr416vzi3lHm3Xm+QZh4qHij8k3Er13kZr5YhL7/+kBAx84kDmPc7HMexLmwisjDCeDIKNFp8mDlQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-arm64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.3.0.tgz", - "integrity": "sha512-dGhVBlllt4iHwTGy21IEoMOTN5wZoid19zEIxsdY29xcEiOEHqzDa7Sqrkh5OE7LKCowL61eFJXxYe/+pYa7ZQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-x64": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.3.0.tgz", - "integrity": "sha512-h8wRfHeLEbU3NzaP1Oku7BYXCJQiTRr+8U0lklyOQXxXiEpHLL8tk1hFl+tezoRKLcPJD7joKaK74ASsqt3Ekg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.3.0.tgz", - "integrity": "sha512-wP4VgR/gfV18sylTuym3sxRTkAgUR2vh6YLeX/GEznk5jCYcYSlx585XlcUcl0c8UffIZlRJ09raWSX3JDb4GA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-gnu": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.3.0.tgz", - "integrity": "sha512-v/14JCYVkqRSJeQbxFx4oUkwVQQw6lFMN7bd4vuARBc3X2lmomkxBsc+BFiIDL/BK+CTx5AOh/k9XmqDnKWRVg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-musl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.3.0.tgz", - "integrity": "sha512-tNhfYqFH5OxtRzfkTOKdgFYlPSZnlDLNW4+leNEvQZhwTJxoTwsZAAhR97l3qVry/kkLyJPBK+Q8EAJLPinDIg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-gnu": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.3.0.tgz", - "integrity": "sha512-pw77m8QywdsoFdFOgmc8roF1inBI0rciqzO8ffRUgLoq7+ee9o5eFqtEcS6hHOOplgifAUUisP8cAnwl9nUYPw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-musl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.3.0.tgz", - "integrity": "sha512-tJs7v2MnV2F8w6X1UpPHl/43OfxjUy9SuJ2ZPoxn79v9vYteChVYO/ueLHCpRMmyTUIVML3N9z4azl9ENH8Xxg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-arm64-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.3.0.tgz", - "integrity": "sha512-OKGxp6kATQdTyI2DF+e9s+hB3/QZB45b6e+dzcfW1SUqiF6CviWyevhmT4USsMEdP3mlpC9zxLz3Oh+WaTMOSw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-ia32-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.3.0.tgz", - "integrity": "sha512-DDZ5AH68JJ2ClQFEA1aNnfA7Ybqyeh0644rGbrLOdNehTmzfICHiWSn0OprzYi9HAshTPQvlwrM+bi2kuaIOjQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-x64-msvc": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.3.0.tgz", - "integrity": "sha512-dMvGV8p92GQ8jhNlGIKpyhVZPzJlT258pPrM5q2F8lKcc9Iv9BbfdnhX1OfinYWnb9ms5zLw6MlaMnqLfUkKnQ==", + "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, - "optional": true - }, - "@stencil/core": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.38.0.tgz", - "integrity": "sha512-oC3QFKO0X1yXVvETgc8OLY525MNKhn9vISBrbtKnGoPlokJ6rI8Vk1RK22TevnNrHLI4SExNLbcDnqilKR35JQ==", - "requires": { - "@rollup/rollup-darwin-arm64": "4.34.9", - "@rollup/rollup-darwin-x64": "4.34.9", - "@rollup/rollup-linux-arm64-gnu": "4.34.9", - "@rollup/rollup-linux-arm64-musl": "4.34.9", - "@rollup/rollup-linux-x64-gnu": "4.34.9", - "@rollup/rollup-linux-x64-musl": "4.34.9", - "@rollup/rollup-win32-arm64-msvc": "4.34.9", - "@rollup/rollup-win32-x64-msvc": "4.34.9" - }, - "dependencies": { - "@rollup/rollup-darwin-arm64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz", - "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==", - "optional": true - }, - "@rollup/rollup-darwin-x64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz", - "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==", - "optional": true - }, - "@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz", - "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==", - "optional": true - }, - "@rollup/rollup-linux-arm64-musl": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz", - "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==", - "optional": true - }, - "@rollup/rollup-linux-x64-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz", - "integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==", - "optional": true - }, - "@rollup/rollup-linux-x64-musl": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz", - "integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==", - "optional": true - }, - "@rollup/rollup-win32-arm64-msvc": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz", - "integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==", - "optional": true - }, - "@rollup/rollup-win32-x64-msvc": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz", - "integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==", - "optional": true - } - } - }, - "@types/estree": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.4.tgz", - "integrity": "sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw==", - "dev": true - }, - "@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.14", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", - "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "@types/node": { - "version": "14.18.63", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", - "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", - "dev": true - }, - "@types/prop-types": { - "version": "15.7.9", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.9.tgz", - "integrity": "sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==", - "dev": true - }, - "@types/react": { - "version": "17.0.79", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.79.tgz", - "integrity": "sha512-gavKA8AwJAML9zWHuiQRASjrrPJHbT/zrUDHiUGUf+l5a3pkEd6atvjjq+8y2vfRHBJLQJjFpxSa9I8qe9zHAw==", - "dev": true, - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "@types/react-dom": { - "version": "17.0.25", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.25.tgz", - "integrity": "sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA==", - "dev": true, - "requires": { - "@types/react": "^17" - } - }, - "@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "dev": true, - "requires": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "dev": true, - "requires": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "@types/scheduler": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "dev": true - }, - "@types/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - } - }, - "@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - } - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true - }, - "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" - } - }, - "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" - } - }, - "array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - } - }, - "array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" - } - }, - "array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - } - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true - }, - "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" - } - }, - "call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dev": true, - "requires": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "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" - } - }, - "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 - }, - "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" - } - }, - "csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "dev": true - }, - "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" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - } - }, - "define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "requires": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "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 - }, - "enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - } - }, - "es-abstract": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", - "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.5", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.2", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.12", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.13" - } - }, - "es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" - } - }, - "es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - } - } - }, - "eslint-config-prettier": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", - "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", - "dev": true, - "requires": { - "get-stdin": "^6.0.0" - } - }, - "eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "requires": { - "debug": "^3.2.7" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", - "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", - "dev": true, - "requires": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "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 - }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "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 - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "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" - } - }, - "flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "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.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true - }, - "function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - } - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dev": true, - "requires": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - } - }, - "get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "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" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "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 - }, - "has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.2" - } - }, - "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dev": true, - "requires": { - "function-bind": "^1.1.2" - } - }, - "history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "dev": true, - "requires": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dev": true, - "requires": { - "react-is": "^16.7.0" - } - }, - "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.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 - }, - "internal-slot": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", - "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.2", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - } - }, - "ionicons": { - "version": "8.0.13", - "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-8.0.13.tgz", - "integrity": "sha512-2QQVyG2P4wszne79jemMjWYLp0DBbDhr4/yFroPCxvPP1wtMxgdIV3l5n+XZ5E9mgoXU79w7yTWpm2XzJsISxQ==", - "requires": { - "@stencil/core": "^4.35.3" - } - }, - "is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - } - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "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-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "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-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dev": true, - "requires": { - "which-typed-array": "^1.1.11" - } - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "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" - } - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "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" - } - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "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" - } - }, - "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" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "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 - }, - "natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" - } - }, - "object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "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" - } - }, - "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "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 - }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", - "dev": true - }, - "regexp.prototype.flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "rollup": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.3.0.tgz", - "integrity": "sha512-scIi1NrKLDIYSPK66jjECtII7vIgdAMFmFo8h6qm++I6nN9qDSV35Ku6erzGVqYjx+lj+j5wkusRMr++8SyDZg==", - "dev": true, - "requires": { - "@rollup/rollup-android-arm-eabi": "4.3.0", - "@rollup/rollup-android-arm64": "4.3.0", - "@rollup/rollup-darwin-arm64": "4.3.0", - "@rollup/rollup-darwin-x64": "4.3.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.3.0", - "@rollup/rollup-linux-arm64-gnu": "4.3.0", - "@rollup/rollup-linux-arm64-musl": "4.3.0", - "@rollup/rollup-linux-x64-gnu": "4.3.0", - "@rollup/rollup-linux-x64-musl": "4.3.0", - "@rollup/rollup-win32-arm64-msvc": "4.3.0", - "@rollup/rollup-win32-ia32-msvc": "4.3.0", - "@rollup/rollup-win32-x64-msvc": "4.3.0", - "fsevents": "~2.3.2" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - } - } - }, - "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - } - }, - "scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", - "dev": true, - "requires": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - } - }, - "set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", - "dev": true, - "requires": { - "define-data-property": "^1.0.1", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" - } - }, - "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 - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.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 - }, - "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" - } - }, - "string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.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": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "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 - }, - "table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "tiny-invariant": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", - "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", - "dev": true - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", - "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" - } - }, - "tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - } - }, - "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "v8-compile-cache": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", - "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", - "dev": true - }, - "value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", - "dev": true - }, - "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" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.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 - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "license": "ISC" } } } diff --git a/packages/react-router/package.json b/packages/react-router/package.json index 7e2f11fc05b..19c5a3872a5 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -42,8 +42,8 @@ "peerDependencies": { "react": ">=16.8.6", "react-dom": ">=16.8.6", - "react-router": "^5.0.1", - "react-router-dom": "^5.0.1" + "react-router": ">=6.0.0", + "react-router-dom": ">=6.0.0" }, "devDependencies": { "@ionic/eslint-config": "^0.3.0", @@ -52,16 +52,15 @@ "@types/node": "^14.0.14", "@types/react": "^17.0.79", "@types/react-dom": "^17.0.25", - "@types/react-router": "^5.0.3", - "@types/react-router-dom": "^5.1.5", + "history": "^5.3.0", "@typescript-eslint/eslint-plugin": "^5.48.2", "@typescript-eslint/parser": "^5.48.2", "eslint": "^7.32.0", "prettier": "^2.8.3", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-router": "^5.0.1", - "react-router-dom": "^5.0.1", + "react-router": "^6.30.0", + "react-router-dom": "^6.30.0", "rimraf": "^3.0.2", "rollup": "^4.2.0", "typescript": "^4.0.5" diff --git a/packages/react-router/scripts/sync.sh b/packages/react-router/scripts/sync.sh index b8f03de4cf2..c69a98efc99 100644 --- a/packages/react-router/scripts/sync.sh +++ b/packages/react-router/scripts/sync.sh @@ -2,14 +2,14 @@ set -e -# Copy ionic react dist -rm -rf node_modules/@ionic/react/dist node_modules/@ionic/react/css -cp -a ../react/dist node_modules/@ionic/react/dist -cp -a ../react/css node_modules/@ionic/react/css -cp -a ../react/package.json node_modules/@ionic/react/package.json - -# Copy core dist -rm -rf node_modules/@ionic/core/dist node_modules/@ionic/core/components -cp -a ../../core/dist node_modules/@ionic/core/dist -cp -a ../../core/components node_modules/@ionic/core/components -cp -a ../../core/package.json node_modules/@ionic/core/package.json +# Delete old packages +rm -f *.tgz + +# Pack @ionic/react +npm pack ../react + +# Pack @ionic/core +npm pack ../../core + +# Install Dependencies +npm install *.tgz --no-save diff --git a/packages/react-router/scripts/test_runner.sh b/packages/react-router/scripts/test_runner.sh new file mode 100755 index 00000000000..9e616448a88 --- /dev/null +++ b/packages/react-router/scripts/test_runner.sh @@ -0,0 +1,68 @@ +#!/bin/bash +set -x + +# Change to script's directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Inside core +echo "Building core..." +cd ../../../core +npm run build + +# Inside packages/react +echo "Building packages/react..." +cd ../packages/react +npm ci +npm run sync +npm run build + +# Inside packages/react-router +echo "Building packages/react-router..." +cd ../react-router +npm ci +npm run sync +npm run build + +# Inside packages/react-router/test +echo "Building test app..." +cd ./test +rm -rf build/reactrouter6 || true +sh ./build.sh reactrouter6 +cd build/reactrouter6 +echo "Installing dependencies..." +npm install --legacy-peer-deps > npm_install.log 2>&1 +npm run sync + +echo "Cleaning up port 3000..." +lsof -ti:3000 | xargs kill -9 || true + +echo "Starting server..." +# Start server in background and save PID +npm start > server.log 2>&1 & +SERVER_PID=$! + +# Ensure server is killed on script exit +trap "kill $SERVER_PID" EXIT + +echo "Waiting for server to start (30s)..." +sleep 30 + +echo "Checking server status..." +SERVER_RESPONSE=$(curl -s -v http://localhost:3000 2>&1) +if echo "$SERVER_RESPONSE" | grep -q "Child compilation failed"; then + echo "Server started but has compilation errors. Exiting." + echo "$SERVER_RESPONSE" + exit 1 +fi + +if ! echo "$SERVER_RESPONSE" | grep -q "200 OK"; then + echo "Server did not return 200 OK. Exiting." + echo "$SERVER_RESPONSE" + exit 1 +fi +echo "Server is healthy." + +echo "Running Cypress tests..." +npm run cypress + diff --git a/packages/react-router/src/ReactRouter/IonReactHashRouter.tsx b/packages/react-router/src/ReactRouter/IonReactHashRouter.tsx index 7908a0f25ec..a216ee60fb6 100644 --- a/packages/react-router/src/ReactRouter/IonReactHashRouter.tsx +++ b/packages/react-router/src/ReactRouter/IonReactHashRouter.tsx @@ -1,53 +1,55 @@ -import type { Action as HistoryAction, History, Location as HistoryLocation } from 'history'; -import { createHashHistory as createHistory } from 'history'; -import React from 'react'; -import type { BrowserRouterProps } from 'react-router-dom'; -import { Router } from 'react-router-dom'; +/** + * `IonReactHashRouter` provides a way to use hash-based routing in Ionic + * React applications. + */ + +import type { Action as HistoryAction, Location as HistoryLocation } from 'history'; +import type { PropsWithChildren } from 'react'; +import React, { useEffect, useRef } from 'react'; +import type { HashRouterProps } from 'react-router-dom'; +import { HashRouter, useLocation, useNavigationType } from 'react-router-dom'; import { IonRouter } from './IonRouter'; -interface IonReactHashRouterProps extends BrowserRouterProps { - history?: History; -} +const RouterContent = ({ children }: PropsWithChildren<{}>) => { + const location = useLocation(); + const navigationType = useNavigationType(); -export class IonReactHashRouter extends React.Component { - history: History; - historyListenHandler?: (location: HistoryLocation, action: HistoryAction) => void; + const historyListenHandler = useRef<(location: HistoryLocation, action: HistoryAction) => void>(); - constructor(props: IonReactHashRouterProps) { - super(props); - const { history, ...rest } = props; - this.history = history || createHistory(rest); - this.history.listen(this.handleHistoryChange.bind(this)); - this.registerHistoryListener = this.registerHistoryListener.bind(this); - } + const registerHistoryListener = (cb: (location: HistoryLocation, action: HistoryAction) => void) => { + historyListenHandler.current = cb; + }; /** - * history@4.x passes separate location and action - * params. history@5.x passes location and action - * together as a single object. - * TODO: If support for React Router <=5 is dropped - * this logic is no longer needed. We can just assume - * a single object with both location and action. + * Processes navigation changes within the application. + * + * Its purpose is to relay the current `location` and the associated + * `action` ('PUSH', 'POP', or 'REPLACE') to any registered listeners, + * primarily for `IonRouter` to manage Ionic-specific UI updates and + * navigation stack behavior. + * + * @param location The current browser history location object. + * @param action The type of navigation action ('PUSH', 'POP', or + * 'REPLACE'). */ - handleHistoryChange(location: HistoryLocation, action: HistoryAction) { - const locationValue = (location as any).location || location; - const actionValue = (location as any).action || action; - if (this.historyListenHandler) { - this.historyListenHandler(locationValue, actionValue); + const handleHistoryChange = (location: HistoryLocation, action: HistoryAction) => { + if (historyListenHandler.current) { + historyListenHandler.current(location, action); } - } - - registerHistoryListener(cb: (location: HistoryLocation, action: HistoryAction) => void) { - this.historyListenHandler = cb; - } - - render() { - const { children, ...props } = this.props; - return ( - - {children} - - ); - } -} + }; + + useEffect(() => { + handleHistoryChange(location, navigationType); + }, [location, navigationType]); + + return {children}; +}; + +export const IonReactHashRouter = ({ children, ...routerProps }: PropsWithChildren) => { + return ( + + {children} + + ); +}; diff --git a/packages/react-router/src/ReactRouter/IonReactMemoryRouter.tsx b/packages/react-router/src/ReactRouter/IonReactMemoryRouter.tsx index c3bf8d74bbc..8f2ff229890 100644 --- a/packages/react-router/src/ReactRouter/IonReactMemoryRouter.tsx +++ b/packages/react-router/src/ReactRouter/IonReactMemoryRouter.tsx @@ -1,51 +1,56 @@ -import type { Action as HistoryAction, Location as HistoryLocation, MemoryHistory } from 'history'; -import React from 'react'; +/** + * `IonReactMemoryRouter` provides a way to use `react-router` in + * environments where a traditional browser history (like `BrowserRouter`) + * isn't available or desirable. + */ + +import type { Action as HistoryAction, Location as HistoryLocation } from 'history'; +import type { PropsWithChildren } from 'react'; +import React, { useEffect, useRef } from 'react'; import type { MemoryRouterProps } from 'react-router'; -import { Router } from 'react-router'; +import { MemoryRouter, useLocation, useNavigationType } from 'react-router'; import { IonRouter } from './IonRouter'; -interface IonReactMemoryRouterProps extends MemoryRouterProps { - history: MemoryHistory; -} +const RouterContent = ({ children }: PropsWithChildren<{}>) => { + const location = useLocation(); + const navigationType = useNavigationType(); -export class IonReactMemoryRouter extends React.Component { - history: MemoryHistory; - historyListenHandler?: (location: HistoryLocation, action: HistoryAction) => void; + const historyListenHandler = useRef<(location: HistoryLocation, action: HistoryAction) => void>(); - constructor(props: IonReactMemoryRouterProps) { - super(props); - this.history = props.history; - this.history.listen(this.handleHistoryChange.bind(this)); - this.registerHistoryListener = this.registerHistoryListener.bind(this); - } + const registerHistoryListener = (cb: (location: HistoryLocation, action: HistoryAction) => void) => { + historyListenHandler.current = cb; + }; /** - * history@4.x passes separate location and action - * params. history@5.x passes location and action - * together as a single object. - * TODO: If support for React Router <=5 is dropped - * this logic is no longer needed. We can just assume - * a single object with both location and action. + * Processes navigation changes within the application. + * + * Its purpose is to relay the current `location` and the associated + * `action` ('PUSH', 'POP', or 'REPLACE') to any registered listeners, + * primarily for `IonRouter` to manage Ionic-specific UI updates and + * navigation stack behavior. + * + * @param location The current browser history location object. + * @param action The type of navigation action ('PUSH', 'POP', or + * 'REPLACE'). */ - handleHistoryChange(location: HistoryLocation, action: HistoryAction) { - const locationValue = (location as any).location || location; - const actionValue = (location as any).action || action; - if (this.historyListenHandler) { - this.historyListenHandler(locationValue, actionValue); + const handleHistoryChange = (location: HistoryLocation, action: HistoryAction) => { + if (historyListenHandler.current) { + historyListenHandler.current(location, action); } - } - - registerHistoryListener(cb: (location: HistoryLocation, action: HistoryAction) => void) { - this.historyListenHandler = cb; - } - - render() { - const { children, ...props } = this.props; - return ( - - {children} - - ); - } -} + }; + + useEffect(() => { + handleHistoryChange(location, navigationType); + }, [location, navigationType]); + + return {children}; +}; + +export const IonReactMemoryRouter = ({ children, ...routerProps }: PropsWithChildren) => { + return ( + + {children} + + ); +}; diff --git a/packages/react-router/src/ReactRouter/IonReactRouter.tsx b/packages/react-router/src/ReactRouter/IonReactRouter.tsx index 0bde5599165..f34a5b5d118 100644 --- a/packages/react-router/src/ReactRouter/IonReactRouter.tsx +++ b/packages/react-router/src/ReactRouter/IonReactRouter.tsx @@ -1,53 +1,65 @@ -import type { Action as HistoryAction, History, Location as HistoryLocation } from 'history'; -import { createBrowserHistory as createHistory } from 'history'; -import React from 'react'; +/** + * `IonReactRouter` facilitates the integration of Ionic's specific + * navigation and UI management with the standard React Router mechanisms, + * allowing an inner Ionic-specific router (`IonRouter`) to react to + * navigation events. + */ + +import type { Action as HistoryAction, Location as HistoryLocation } from 'history'; +import type { PropsWithChildren } from 'react'; +import React, { useEffect, useRef, useCallback } from 'react'; import type { BrowserRouterProps } from 'react-router-dom'; -import { Router } from 'react-router-dom'; +import { BrowserRouter, useLocation, useNavigationType } from 'react-router-dom'; import { IonRouter } from './IonRouter'; -interface IonReactRouterProps extends BrowserRouterProps { - history?: History; -} +/** + * This component acts as a bridge to ensure React Router hooks like + * `useLocation` and `useNavigationType` are called within the valid + * context of a ``. + * + * It was split from `IonReactRouter` because these hooks must be + * descendants of a `` component, which `BrowserRouter` provides. + */ +const RouterContent = ({ children }: PropsWithChildren<{}>) => { + const location = useLocation(); + const navigationType = useNavigationType(); -export class IonReactRouter extends React.Component { - historyListenHandler?: (location: HistoryLocation, action: HistoryAction) => void; - history: History; + const historyListenHandler = useRef<(location: HistoryLocation, action: HistoryAction) => void>(); - constructor(props: IonReactRouterProps) { - super(props); - const { history, ...rest } = props; - this.history = history || createHistory(rest); - this.history.listen(this.handleHistoryChange.bind(this)); - this.registerHistoryListener = this.registerHistoryListener.bind(this); - } + const registerHistoryListener = useCallback((cb: (location: HistoryLocation, action: HistoryAction) => void) => { + historyListenHandler.current = cb; + }, []); /** - * history@4.x passes separate location and action - * params. history@5.x passes location and action - * together as a single object. - * TODO: If support for React Router <=5 is dropped - * this logic is no longer needed. We can just assume - * a single object with both location and action. + * Processes navigation changes within the application. + * + * Its purpose is to relay the current `location` and the associated + * `action` ('PUSH', 'POP', or 'REPLACE') to any registered listeners, + * primarily for `IonRouter` to manage Ionic-specific UI updates and + * navigation stack behavior. + * + * @param loc The current browser history location object. + * @param act The type of navigation action ('PUSH', 'POP', or + * 'REPLACE'). */ - handleHistoryChange(location: HistoryLocation, action: HistoryAction) { - const locationValue = (location as any).location || location; - const actionValue = (location as any).action || action; - if (this.historyListenHandler) { - this.historyListenHandler(locationValue, actionValue); + const handleHistoryChange = useCallback((loc: HistoryLocation, act: HistoryAction) => { + if (historyListenHandler.current) { + historyListenHandler.current(loc, act); } - } - - registerHistoryListener(cb: (location: HistoryLocation, action: HistoryAction) => void) { - this.historyListenHandler = cb; - } - - render() { - const { children, ...props } = this.props; - return ( - - {children} - - ); - } -} + }, []); + + useEffect(() => { + handleHistoryChange(location, navigationType); + }, [location, navigationType, handleHistoryChange]); + + return {children}; +}; + +export const IonReactRouter = ({ children, ...browserRouterProps }: PropsWithChildren) => { + return ( + + {children} + + ); +}; diff --git a/packages/react-router/src/ReactRouter/IonRouteInner.tsx b/packages/react-router/src/ReactRouter/IonRouteInner.tsx index ddeb0e74d31..4d3a440df85 100644 --- a/packages/react-router/src/ReactRouter/IonRouteInner.tsx +++ b/packages/react-router/src/ReactRouter/IonRouteInner.tsx @@ -1,30 +1,7 @@ import type { IonRouteProps } from '@ionic/react'; import React from 'react'; -import { Route } from 'react-router'; +import { Route } from 'react-router-dom'; -export class IonRouteInner extends React.PureComponent { - render() { - return ( - - ); - } -} +export const IonRouteInner = ({ path, element }: IonRouteProps) => { + return ; +}; diff --git a/packages/react-router/src/ReactRouter/IonRouter.tsx b/packages/react-router/src/ReactRouter/IonRouter.tsx index fcadd6561a6..f1d475a733b 100644 --- a/packages/react-router/src/ReactRouter/IonRouter.tsx +++ b/packages/react-router/src/ReactRouter/IonRouter.tsx @@ -1,182 +1,298 @@ +/** + * `IonRouter` is responsible for managing the application's navigation + * state, tracking the history of visited routes, and coordinating + * transitions between different views. It intercepts route changes from + * React Router and translates them into actions that Ionic can understand + * and animate. + */ + import type { AnimationBuilder, RouteAction, RouteInfo, RouteManagerContextState, RouterDirection, - ViewItem, + RouterOptions, } from '@ionic/react'; import { LocationHistory, NavManager, RouteManagerContext, generateId, getConfig } from '@ionic/react'; -import type { Action as HistoryAction, Location as HistoryLocation } from 'history'; -import React from 'react'; -import type { RouteComponentProps } from 'react-router-dom'; -import { withRouter } from 'react-router-dom'; +import type { Action as HistoryAction, Location } from 'history'; +import type { PropsWithChildren } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; import { IonRouteInner } from './IonRouteInner'; import { ReactRouterViewStack } from './ReactRouterViewStack'; import StackManager from './StackManager'; +// Use Location directly - state is typed as `unknown` in history v5 +type HistoryLocation = Location; + export interface LocationState { direction?: RouterDirection; - routerOptions?: { as?: string; unmount?: boolean }; + routerOptions?: RouterOptions; } -interface IonRouteProps extends RouteComponentProps<{}, {}, LocationState> { - registerHistoryListener: (cb: (location: HistoryLocation, action: HistoryAction) => void) => void; +interface IonRouterProps { + registerHistoryListener: (cb: (location: HistoryLocation, action: HistoryAction) => void) => void; } -interface IonRouteState { - routeInfo: RouteInfo; -} - -class IonRouterInner extends React.PureComponent { - currentTab?: string; - exitViewFromOtherOutletHandlers: ((pathname: string) => ViewItem | undefined)[] = []; - incomingRouteParams?: Partial; - locationHistory = new LocationHistory(); - viewStack = new ReactRouterViewStack(); - routeMangerContextState: RouteManagerContextState = { - canGoBack: () => this.locationHistory.canGoBack(), - clearOutlet: this.viewStack.clear, - findViewItemByPathname: this.viewStack.findViewItemByPathname, - getChildrenToRender: this.viewStack.getChildrenToRender, - goBack: () => this.handleNavigateBack(), - createViewItem: this.viewStack.createViewItem, - findViewItemByRouteInfo: this.viewStack.findViewItemByRouteInfo, - findLeavingViewItemByRouteInfo: this.viewStack.findLeavingViewItemByRouteInfo, - addViewItem: this.viewStack.add, - unMountViewItem: this.viewStack.remove, - }; +type RouteParams = Record; +type SafeRouteParams = Record; - constructor(props: IonRouteProps) { - super(props); +const filterUndefinedParams = (params: RouteParams): SafeRouteParams => { + const result: SafeRouteParams = {}; + for (const key of Object.keys(params)) { + const value = params[key]; + if (value !== undefined) { + result[key] = value; + } + } + return result; +}; - const routeInfo = { - id: generateId('routeInfo'), - pathname: this.props.location.pathname, - search: this.props.location.search, - }; +const areParamsEqual = (a?: RouteParams, b?: RouteParams) => { + const paramsA = a || {}; + const paramsB = b || {}; + const keysA = Object.keys(paramsA); + const keysB = Object.keys(paramsB); - this.locationHistory.add(routeInfo); - this.handleChangeTab = this.handleChangeTab.bind(this); - this.handleResetTab = this.handleResetTab.bind(this); - this.handleNativeBack = this.handleNativeBack.bind(this); - this.handleNavigate = this.handleNavigate.bind(this); - this.handleNavigateBack = this.handleNavigateBack.bind(this); - this.props.registerHistoryListener(this.handleHistoryChange.bind(this)); - this.handleSetCurrentTab = this.handleSetCurrentTab.bind(this); - - this.state = { - routeInfo, - }; + if (keysA.length !== keysB.length) { + return false; } - handleChangeTab(tab: string, path?: string, routeOptions?: any) { - if (!path) { + return keysA.every((key) => { + const valueA = paramsA[key]; + const valueB = paramsB[key]; + if (Array.isArray(valueA) && Array.isArray(valueB)) { + if (valueA.length !== valueB.length) { + return false; + } + return valueA.every((entry, idx) => entry === valueB[idx]); + } + return valueA === valueB; + }); +}; + +export const IonRouter = ({ children, registerHistoryListener }: PropsWithChildren) => { + const location = useLocation(); + const navigate = useNavigate(); + + const didMountRef = useRef(false); + const locationHistory = useRef(new LocationHistory()); + const currentTab = useRef(undefined); + const viewStack = useRef(new ReactRouterViewStack()); + const incomingRouteParams = useRef | null>(null); + + const [routeInfo, setRouteInfo] = useState({ + id: generateId('routeInfo'), + pathname: location.pathname, + search: location.search, + params: {}, + }); + + useEffect(() => { + if (didMountRef.current) { return; } - const routeInfo = this.locationHistory.getCurrentRouteInfoForTab(tab); - const [pathname, search] = path.split('?'); - if (routeInfo) { - this.incomingRouteParams = { ...routeInfo, routeAction: 'push', routeDirection: 'none' }; - if (routeInfo.pathname === pathname) { - this.incomingRouteParams.routeOptions = routeOptions; - this.props.history.push(routeInfo.pathname + (routeInfo.search || '')); - } else { - this.incomingRouteParams.pathname = pathname; - this.incomingRouteParams.search = search ? '?' + search : undefined; - this.incomingRouteParams.routeOptions = routeOptions; - this.props.history.push(pathname + (search ? '?' + search : '')); + // Seed the history stack with the initial location and begin listening + // for future navigations once React has committed the mount. This avoids + // duplicate entries when React StrictMode runs an extra render pre-commit. + locationHistory.current.add(routeInfo); + registerHistoryListener(handleHistoryChange); + + didMountRef.current = true; + }, []); + + useEffect(() => { + const activeView = viewStack.current.findViewItemByRouteInfo(routeInfo, undefined, true); + const matchedParams = activeView?.routeData.match?.params as RouteParams | undefined; + + if (matchedParams) { + const paramsCopy = filterUndefinedParams({ ...matchedParams }); + if (areParamsEqual(routeInfo.params as RouteParams | undefined, paramsCopy)) { + return; } - } else { - this.handleNavigate(pathname, 'push', 'none', undefined, routeOptions, tab); + + const updatedRouteInfo: RouteInfo = { + ...routeInfo, + params: paramsCopy, + }; + locationHistory.current.update(updatedRouteInfo); + setRouteInfo(updatedRouteInfo); } - } + }, [routeInfo]); - handleHistoryChange(location: HistoryLocation, action: HistoryAction) { + /** + * Triggered whenever the history changes, either through user navigation + * or programmatic changes. It transforms the raw browser history changes + * into `RouteInfo` objects, which are needed Ionic's animations and + * navigation patterns. + * + * @param location The current location object from the history. + * @param action The action that triggered the history change. + */ + const handleHistoryChange = (location: HistoryLocation, action: HistoryAction) => { let leavingLocationInfo: RouteInfo; - if (this.incomingRouteParams) { - if (this.incomingRouteParams.routeAction === 'replace') { - leavingLocationInfo = this.locationHistory.previous(); + /** + * A programmatic navigation was triggered. + * e.g., ``, `history.push()`, or `handleNavigate()` + */ + if (incomingRouteParams.current) { + /** + * The current history entry is overwritten, so the previous entry + * is the one we are leaving. + */ + if (incomingRouteParams.current?.routeAction === 'replace') { + leavingLocationInfo = locationHistory.current.previous(); } else { - leavingLocationInfo = this.locationHistory.current(); + // If the action is 'push' or 'pop', we want to use the current route. + leavingLocationInfo = locationHistory.current.current(); } } else { - leavingLocationInfo = this.locationHistory.current(); + /** + * An external navigation was triggered + * e.g., browser back/forward button or direct link + * + * The leaving location is the current route. + */ + leavingLocationInfo = locationHistory.current.current(); } const leavingUrl = leavingLocationInfo.pathname + leavingLocationInfo.search; if (leavingUrl !== location.pathname) { - if (!this.incomingRouteParams) { + if (!incomingRouteParams.current) { + // Determine if the destination is a tab route by checking if it matches + // the pattern of tab routes (containing /tabs/ in the path) + const isTabRoute = /\/tabs(\/|$)/.test(location.pathname); + const tabToUse = isTabRoute ? currentTab.current : undefined; + + // If we're leaving tabs entirely, clear the current tab + if (!isTabRoute && currentTab.current) { + currentTab.current = undefined; + } + + /** + * A `REPLACE` action can be triggered by React Router's + * `` component. + */ if (action === 'REPLACE') { - this.incomingRouteParams = { + incomingRouteParams.current = { routeAction: 'replace', routeDirection: 'none', - tab: this.currentTab, + tab: tabToUse, }; } + /** + * A `POP` action can be triggered by the browser's back/forward + * button. + */ if (action === 'POP') { - const currentRoute = this.locationHistory.current(); + const currentRoute = locationHistory.current.current(); + /** + * Check if the current route was "pushed" by a previous route + * (indicates a linear history path). + */ if (currentRoute && currentRoute.pushedByRoute) { - const prevInfo = this.locationHistory.findLastLocation(currentRoute); - this.incomingRouteParams = { ...prevInfo, routeAction: 'pop', routeDirection: 'back' }; + const prevInfo = locationHistory.current.findLastLocation(currentRoute); + incomingRouteParams.current = { ...prevInfo, routeAction: 'pop', routeDirection: 'back' }; + // It's a non-linear history path like a direct link. } else { - this.incomingRouteParams = { + incomingRouteParams.current = { routeAction: 'pop', routeDirection: 'none', - tab: this.currentTab, + tab: tabToUse, }; } } - if (!this.incomingRouteParams) { - this.incomingRouteParams = { + if (!incomingRouteParams.current) { + const state = location.state as LocationState | null; + incomingRouteParams.current = { routeAction: 'push', - routeDirection: location.state?.direction || 'forward', - routeOptions: location.state?.routerOptions, - tab: this.currentTab, + routeDirection: state?.direction || 'forward', + routeOptions: state?.routerOptions, + tab: tabToUse, }; } } let routeInfo: RouteInfo; - if (this.incomingRouteParams?.id) { + // If we're navigating away from tabs to a non-tab route, clear the current tab + if (!/\/tabs(\/|$)/.test(location.pathname) && currentTab.current) { + currentTab.current = undefined; + } + + /** + * An existing id indicates that it's re-activating an existing route. + * e.g., tab switching or navigating back to a previous route + */ + if (incomingRouteParams.current?.id) { routeInfo = { - ...(this.incomingRouteParams as RouteInfo), + ...(incomingRouteParams.current as RouteInfo), lastPathname: leavingLocationInfo.pathname, }; - this.locationHistory.add(routeInfo); + locationHistory.current.add(routeInfo); + /** + * A new route is being created since it's not re-activating + * an existing route. + */ } else { const isPushed = - this.incomingRouteParams.routeAction === 'push' && this.incomingRouteParams.routeDirection === 'forward'; + incomingRouteParams.current?.routeAction === 'push' && + incomingRouteParams.current.routeDirection === 'forward'; routeInfo = { id: generateId('routeInfo'), - ...this.incomingRouteParams, - lastPathname: leavingLocationInfo.pathname, - pathname: location.pathname, + ...incomingRouteParams.current, + lastPathname: leavingLocationInfo.pathname, // The URL we just came from + pathname: location.pathname, // The current (destination) URL search: location.search, - params: this.props.match.params, + params: incomingRouteParams.current?.params + ? filterUndefinedParams(incomingRouteParams.current.params as RouteParams) + : {}, prevRouteLastPathname: leavingLocationInfo.lastPathname, }; if (isPushed) { - routeInfo.tab = leavingLocationInfo.tab; + // Only inherit tab from leaving route if we don't already have one. + // This preserves tab context for same-tab navigation while allowing cross-tab navigation. + routeInfo.tab = routeInfo.tab || leavingLocationInfo.tab; routeInfo.pushedByRoute = leavingLocationInfo.pathname; + // Triggered by a browser back button or handleNavigateBack. } else if (routeInfo.routeAction === 'pop') { - const r = this.locationHistory.findLastLocation(routeInfo); + // Find the route that pushed this one. + const r = locationHistory.current.findLastLocation(routeInfo); routeInfo.pushedByRoute = r?.pushedByRoute; + // Navigating to a new tab. } else if (routeInfo.routeAction === 'push' && routeInfo.tab !== leavingLocationInfo.tab) { - // If we are switching tabs grab the last route info for the tab and use its pushedByRoute - const lastRoute = this.locationHistory.getCurrentRouteInfoForTab(routeInfo.tab); - routeInfo.pushedByRoute = lastRoute?.pushedByRoute; + /** + * If we are switching tabs grab the last route info for the + * tab and use its `pushedByRoute`. + */ + const lastRoute = locationHistory.current.getCurrentRouteInfoForTab(routeInfo.tab); + /** + * Tab bar switches (direction 'none') should not create cross-tab back + * navigation. Only inherit pushedByRoute from the tab's own history. + */ + if (routeInfo.routeDirection === 'none') { + routeInfo.pushedByRoute = lastRoute?.pushedByRoute; + } else { + routeInfo.pushedByRoute = lastRoute?.pushedByRoute ?? leavingLocationInfo.pathname; + } + // Triggered by `history.replace()` or a `` component, etc. } else if (routeInfo.routeAction === 'replace') { - // Make sure to set the lastPathname, etc.. to the current route so the page transitions out - const currentRouteInfo = this.locationHistory.current(); + /** + * Make sure to set the `lastPathname`, etc.. to the current route + * so the page transitions out. + */ + const currentRouteInfo = locationHistory.current.current(); /** - * If going from /home to /child, then replacing from - * /child to /home, we don't want the route info to - * say that /home was pushed by /home which is not correct. + * Special handling for `replace` to ensure correct `pushedByRoute` + * and `lastPathname`. + * + * If going from `/home` to `/child`, then replacing from + * `/child` to `/home`, we don't want the route info to + * say that `/home` was pushed by `/home` which is not correct. */ const currentPushedBy = currentRouteInfo?.pushedByRoute; const pushedByRoute = @@ -198,58 +314,126 @@ class IonRouterInner extends React.PureComponent { routeInfo.routeAnimation = routeInfo.routeAnimation || currentRouteInfo?.routeAnimation; } - this.locationHistory.add(routeInfo); + locationHistory.current.add(routeInfo); } - - this.setState({ - routeInfo, - }); + setRouteInfo(routeInfo); } - this.incomingRouteParams = undefined; - } + incomingRouteParams.current = null; + }; /** - * history@4.x uses goBack(), history@5.x uses back() - * TODO: If support for React Router <=5 is dropped - * this logic is no longer needed. We can just - * assume back() is available. + * Resets the specified tab to its initial, root route. + * + * @param tab The tab to reset. + * @param originalHref The original href for the tab. + * @param originalRouteOptions The original route options for the tab. */ - handleNativeBack() { - const history = this.props.history as any; - const goBack = history.goBack || history.back; - goBack(); - } + const handleResetTab = (tab: string, originalHref: string, originalRouteOptions: any) => { + const routeInfo = locationHistory.current.getFirstRouteInfoForTab(tab); + if (routeInfo) { + const newRouteInfo = { ...routeInfo }; + newRouteInfo.pathname = originalHref; + newRouteInfo.routeOptions = originalRouteOptions; + incomingRouteParams.current = { ...newRouteInfo, routeAction: 'pop', routeDirection: 'back' }; + navigate(newRouteInfo.pathname + (newRouteInfo.search || '')); + } + }; - handleNavigate( - path: string, - routeAction: RouteAction, - routeDirection?: RouterDirection, - routeAnimation?: AnimationBuilder, - routeOptions?: any, - tab?: string - ) { - this.incomingRouteParams = Object.assign(this.incomingRouteParams || {}, { - routeAction, - routeDirection, - routeOptions, - routeAnimation, - tab, - }); + /** + * Handles tab changes. + * + * @param tab The tab to switch to. + * @param path The new path for the tab. + * @param routeOptions Additional route options. + */ + const handleChangeTab = (tab: string, path?: string, routeOptions?: any) => { + if (!path) { + return; + } + + const routeInfo = locationHistory.current.getCurrentRouteInfoForTab(tab); + const [pathname, search] = path.split('?'); + // User has navigated to the current tab before. + if (routeInfo) { + const routeParams = { + ...routeInfo, + routeAction: 'push' as RouteAction, + routeDirection: 'none' as RouterDirection, + }; + /** + * User is navigating to the same tab. + * e.g., `/tabs/home` → `/tabs/home` + */ + if (routeInfo.pathname === pathname) { + incomingRouteParams.current = { + ...routeParams, + routeOptions, + }; + + navigate(routeInfo.pathname + (routeInfo.search || '')); + /** + * User is navigating to a different tab. + * e.g., `/tabs/home` → `/tabs/settings` + */ + } else { + incomingRouteParams.current = { + ...routeParams, + pathname, + search: search ? '?' + search : undefined, + routeOptions, + }; - if (routeAction === 'push') { - this.props.history.push(path); + navigate(pathname + (search ? '?' + search : '')); + } + // User has not navigated to this tab before. } else { - this.props.history.replace(path); + handleNavigate(pathname, 'push', 'none', undefined, routeOptions, tab); } - } + }; + + /** + * Set the current active tab in `locationHistory`. + * This is crucial for maintaining tab history since each tab has + * its own navigation stack. + * + * @param tab The tab to set as active. + */ + const handleSetCurrentTab = (tab: string) => { + currentTab.current = tab; + const ri = { ...locationHistory.current.current() }; + if (ri.tab !== tab) { + ri.tab = tab; + locationHistory.current.update(ri); + } + }; - handleNavigateBack(defaultHref: string | RouteInfo = '/', routeAnimation?: AnimationBuilder) { + /** + * Handles the native back button press. + * It's usually called when a user presses the platform-native back action. + */ + const handleNativeBack = () => { + navigate(-1); + }; + + /** + * Used to manage the back navigation within the Ionic React's routing + * system. It's deeply integrated with Ionic's view lifecycle, animations, + * and its custom history tracking (`locationHistory`) to provide a + * native-like transition and maintain correct application state. + * + * @param defaultHref The fallback URL to navigate to if there's no + * previous entry in the `locationHistory` stack. + * @param routeAnimation A custom animation builder to override the + * default "back" animation. + */ + const handleNavigateBack = (defaultHref: string | RouteInfo = '/', routeAnimation?: AnimationBuilder) => { const config = getConfig(); defaultHref = defaultHref ? defaultHref : config && config.get('backButtonDefaultHref' as any); - const routeInfo = this.locationHistory.current(); + const routeInfo = locationHistory.current.current(); + // It's a linear navigation. if (routeInfo && routeInfo.pushedByRoute) { - const prevInfo = this.locationHistory.findLastLocation(routeInfo); + const prevInfo = locationHistory.current.findLastLocation(routeInfo); if (prevInfo) { /** * This needs to be passed to handleNavigate @@ -257,84 +441,144 @@ class IonRouterInner extends React.PureComponent { * will be overridden. */ const incomingAnimation = routeAnimation || routeInfo.routeAnimation; - this.incomingRouteParams = { + incomingRouteParams.current = { ...prevInfo, routeAction: 'pop', routeDirection: 'back', routeAnimation: incomingAnimation, }; - if ( - routeInfo.lastPathname === routeInfo.pushedByRoute || - /** - * We need to exclude tab switches/tab - * context changes here because tabbed - * navigation is not linear, but router.back() - * will go back in a linear fashion. - */ - (prevInfo.pathname === routeInfo.pushedByRoute && routeInfo.tab === '' && prevInfo.tab === '') - ) { + /** + * Check if it's a simple linear back navigation (not tabbed). + * e.g., `/home` → `/settings` → back to `/home` + */ + const condition1 = routeInfo.lastPathname === routeInfo.pushedByRoute; + const condition2 = prevInfo.pathname === routeInfo.pushedByRoute && routeInfo.tab === '' && prevInfo.tab === ''; + if (condition1 || condition2) { + navigate(-1); + } else { /** - * history@4.x uses goBack(), history@5.x uses back() - * TODO: If support for React Router <=5 is dropped - * this logic is no longer needed. We can just - * assume back() is available. + * It's a non-linear back navigation. + * e.g., direct link or tab switch or nested navigation with redirects */ - const history = this.props.history as any; - const goBack = history.goBack || history.back; - goBack(); - } else { - this.handleNavigate(prevInfo.pathname + (prevInfo.search || ''), 'pop', 'back', incomingAnimation); + handleNavigate(prevInfo.pathname + (prevInfo.search || ''), 'pop', 'back', incomingAnimation); } + /** + * `pushedByRoute` exists, but no corresponding previous entry in + * the history stack. + */ } else { - this.handleNavigate(defaultHref as string, 'pop', 'back', routeAnimation); + handleNavigate(defaultHref as string, 'pop', 'back', routeAnimation); } + /** + * No `pushedByRoute` (e.g., initial page load or tab root). + * Tabs with no back history should not navigate. + */ } else { - this.handleNavigate(defaultHref as string, 'pop', 'back', routeAnimation); + if (routeInfo && routeInfo.tab) { + return; + } + handleNavigate(defaultHref as string, 'pop', 'back', routeAnimation); } - } + }; - handleResetTab(tab: string, originalHref: string, originalRouteOptions: any) { - const routeInfo = this.locationHistory.getFirstRouteInfoForTab(tab); - if (routeInfo) { - const newRouteInfo = { ...routeInfo }; - newRouteInfo.pathname = originalHref; - newRouteInfo.routeOptions = originalRouteOptions; - this.incomingRouteParams = { ...newRouteInfo, routeAction: 'pop', routeDirection: 'back' }; - this.props.history.push(newRouteInfo.pathname + (newRouteInfo.search || '')); - } - } + /** + * Used to programmatically navigate through the app. + * + * @param path The path to navigate to. + * @param routeAction The action to take (push, replace, etc.). + * @param routeDirection The direction of the navigation (forward, + * back, etc.). + * @param routeAnimation The animation to use for the transition. + * @param routeOptions Additional options for the route. + * @param tab The tab to navigate to, if applicable. + */ + const handleNavigate = ( + path: string, + routeAction: RouteAction, + routeDirection?: RouterDirection, + routeAnimation?: AnimationBuilder, + routeOptions?: any, + tab?: string + ) => { + const normalizedRouteDirection = + routeAction === 'push' && routeDirection === undefined ? 'forward' : routeDirection; - handleSetCurrentTab(tab: string) { - this.currentTab = tab; - const ri = { ...this.locationHistory.current() }; - if (ri.tab !== tab) { - ri.tab = tab; - this.locationHistory.update(ri); + // When navigating from tabs context, we need to determine if the destination + // is also within tabs. If not, we should clear the tab context. + let navigationTab = tab; + + // If no explicit tab is provided and we're in a tab context, + // check if the destination path is outside of the current tab context + if (!tab && currentTab.current && path) { + // Get the current route info to understand where we are + const currentRoute = locationHistory.current.current(); + + // If we're navigating from a tab route to a completely different path structure, + // we should clear the tab context. This is a simplified check that assumes + // tab routes share a common parent path. + if (currentRoute && currentRoute.pathname) { + // Extract the base tab path (e.g., /routing/tabs from /routing/tabs/home) + const tabBaseMatch = currentRoute.pathname.match(/^(.*\/tabs)/); + if (tabBaseMatch) { + const tabBasePath = tabBaseMatch[1]; + // If the new path doesn't start with the tab base path, we're leaving tabs + if (!path.startsWith(tabBasePath)) { + currentTab.current = undefined; + navigationTab = undefined; + } else { + // Still within tabs, preserve the tab context + navigationTab = currentTab.current; + } + } + } } - } - render() { - return ( - - - {this.props.children} - - - ); - } -} + const baseParams = incomingRouteParams.current ?? {}; + incomingRouteParams.current = { + ...baseParams, + routeAction, + routeDirection: normalizedRouteDirection, + routeOptions, + routeAnimation, + tab: navigationTab, + }; + + navigate(path, { replace: routeAction !== 'push' }); + }; + + const routeMangerContextValue: RouteManagerContextState = { + canGoBack: () => locationHistory.current.canGoBack(), + clearOutlet: viewStack.current.clear, + findViewItemByPathname: viewStack.current.findViewItemByPathname, + getChildrenToRender: viewStack.current.getChildrenToRender, + getViewItemsForOutlet: viewStack.current.getViewItemsForOutlet.bind(viewStack.current), + goBack: () => handleNavigateBack(), + createViewItem: viewStack.current.createViewItem, + findViewItemByRouteInfo: viewStack.current.findViewItemByRouteInfo, + findLeavingViewItemByRouteInfo: viewStack.current.findLeavingViewItemByRouteInfo, + addViewItem: viewStack.current.add, + unMountViewItem: viewStack.current.remove, + }; + + return ( + + + {children} + + + ); +}; -export const IonRouter = withRouter(IonRouterInner); IonRouter.displayName = 'IonRouter'; diff --git a/packages/react-router/src/ReactRouter/ReactRouterViewStack.tsx b/packages/react-router/src/ReactRouter/ReactRouterViewStack.tsx index 92036790203..32598cb22ba 100644 --- a/packages/react-router/src/ReactRouter/ReactRouterViewStack.tsx +++ b/packages/react-router/src/ReactRouter/ReactRouterViewStack.tsx @@ -1,186 +1,806 @@ +/** + * `ReactRouterViewStack` is a custom navigation manager used in Ionic React + * apps to map React Router route elements (such as ``) to "view + * items" that Ionic can manage in a view stack. This is critical to maintain + * Ionic’s animation, lifecycle, and history behavior across views. + */ + import type { RouteInfo, ViewItem } from '@ionic/react'; -import { IonRoute, ViewLifeCycleManager, ViewStacks, generateId } from '@ionic/react'; +import { IonRoute, ViewLifeCycleManager, ViewStacks } from '@ionic/react'; import React from 'react'; +import type { PathMatch } from 'react-router'; +import { Navigate, UNSAFE_RouteContext as RouteContext } from 'react-router-dom'; + +import { analyzeRouteChildren, computeParentPath } from './utils/computeParentPath'; +import { derivePathnameToMatch, matchPath } from './utils/pathMatching'; +import { normalizePathnameForComparison } from './utils/pathNormalization'; +import { extractRouteChildren, isNavigateElement } from './utils/routeElements'; +import { sortViewsBySpecificity } from './utils/viewItemUtils'; + +/** + * Delay in milliseconds before removing a Navigate view item after a redirect. + * This ensures the redirect navigation completes before the view is removed. + */ +const NAVIGATE_REDIRECT_DELAY_MS = 100; + +/** + * Delay in milliseconds before cleaning up a view without an IonPage element. + * This double-checks that the view is truly not needed before removal. + */ +const VIEW_CLEANUP_DELAY_MS = 200; + +const createDefaultMatch = ( + fullPathname: string, + routeProps: { path?: string; caseSensitive?: boolean; end?: boolean; index?: boolean } +): PathMatch => { + const isIndexRoute = !!routeProps.index; + const patternPath = routeProps.path ?? ''; + const pathnameBase = fullPathname === '' ? '/' : fullPathname; + const computedEnd = + routeProps.end !== undefined ? routeProps.end : patternPath !== '' ? !patternPath.endsWith('*') : true; + + return { + params: {}, + pathname: isIndexRoute ? '' : fullPathname, + pathnameBase, + pattern: { + path: patternPath, + caseSensitive: routeProps.caseSensitive ?? false, + end: isIndexRoute ? true : computedEnd, + }, + }; +}; + +const computeRelativeToParent = (pathname: string, parentPath?: string): string | null => { + if (!parentPath) return null; + const normalizedParent = normalizePathnameForComparison(parentPath); + const normalizedPathname = normalizePathnameForComparison(pathname); + + if (normalizedPathname === normalizedParent) { + return ''; + } + + const withSlash = normalizedParent === '/' ? '/' : normalizedParent + '/'; + if (normalizedPathname.startsWith(withSlash)) { + return normalizedPathname.slice(withSlash.length); + } + return null; +}; -import { matchPath } from './utils/matchPath'; +const resolveIndexRouteMatch = ( + viewItem: ViewItem, + pathname: string, + parentPath?: string +): PathMatch | null => { + if (!viewItem.routeData?.childProps?.index) { + return null; + } + + // Prefer computing against the parent path when available to align with RRv6 semantics + const relative = computeRelativeToParent(pathname, parentPath); + if (relative !== null) { + // Index routes match only when there is no remaining path + if (relative === '' || relative === '/') { + return createDefaultMatch(parentPath || pathname, viewItem.routeData.childProps); + } + return null; + } + + // Fallback: use previously computed match base for equality check + const previousMatch = viewItem.routeData?.match; + if (!previousMatch) { + return null; + } + + const normalizedPathname = normalizePathnameForComparison(pathname); + const normalizedBase = normalizePathnameForComparison(previousMatch.pathnameBase || previousMatch.pathname || ''); + + return normalizedPathname === normalizedBase ? previousMatch : null; +}; export class ReactRouterViewStack extends ViewStacks { + private viewItemCounter = 0; + constructor() { super(); - this.createViewItem = this.createViewItem.bind(this); - this.findViewItemByRouteInfo = this.findViewItemByRouteInfo.bind(this); - this.findLeavingViewItemByRouteInfo = this.findLeavingViewItemByRouteInfo.bind(this); - this.getChildrenToRender = this.getChildrenToRender.bind(this); - this.findViewItemByPathname = this.findViewItemByPathname.bind(this); } - createViewItem(outletId: string, reactElement: React.ReactElement, routeInfo: RouteInfo, page?: HTMLElement) { + /** + * Creates a new view item for the given outlet and react route element. + * Associates route props with the matched route path for further lookups. + */ + createViewItem = (outletId: string, reactElement: React.ReactElement, routeInfo: RouteInfo, page?: HTMLElement) => { + const routePath = reactElement.props.path || ''; + + // Check if we already have a view item for this exact route that we can reuse + // Include wildcard routes like tabs/* since they should be reused + // Also check unmounted items that might have been preserved for browser navigation + const existingViewItem = this.getViewItemsForOutlet(outletId).find((v) => { + const existingRouteProps = v.reactElement?.props ?? {}; + const existingPath = existingRouteProps.path || ''; + const existingElement = existingRouteProps.element; + const newElement = reactElement.props.element; + const existingIsIndexRoute = !!existingRouteProps.index; + const newIsIndexRoute = !!reactElement.props.index; + + // For Navigate components, match by destination + const existingIsNavigate = React.isValidElement(existingElement) && existingElement.type === Navigate; + const newIsNavigate = React.isValidElement(newElement) && newElement.type === Navigate; + if (existingIsNavigate && newIsNavigate) { + const existingTo = (existingElement.props as { to?: string })?.to; + const newTo = (newElement.props as { to?: string })?.to; + if (existingTo === newTo) { + return true; + } + } + + if (existingIsIndexRoute && newIsIndexRoute) { + return true; + } + + // Reuse view items with the same path + // Special case: reuse tabs/* and other specific wildcard routes + // Don't reuse index routes (empty path) or generic catch-all wildcards (*) + if (existingPath === routePath && existingPath !== '' && existingPath !== '*') { + // Parameterized routes need pathname matching to ensure /details/1 and /details/2 + // get separate view items. For wildcard routes (e.g., user/:userId/*), compare + // pathnameBase to allow child path changes while preserving the parent view. + const hasParams = routePath.includes(':'); + const isWildcard = routePath.includes('*'); + if (hasParams) { + if (isWildcard) { + const existingPathnameBase = v.routeData?.match?.pathnameBase; + const newMatch = matchComponent(reactElement, routeInfo.pathname, false); + const newPathnameBase = newMatch?.pathnameBase; + if (existingPathnameBase !== newPathnameBase) { + return false; + } + } else { + const existingPathname = v.routeData?.match?.pathname; + if (existingPathname !== routeInfo.pathname) { + return false; + } + } + } + return true; + } + // Also reuse specific wildcard routes like tabs/* + if (existingPath === routePath && existingPath.endsWith('/*') && existingPath !== '/*') { + return true; + } + return false; + }); + + if (existingViewItem) { + // Update and ensure the existing view item is properly configured + existingViewItem.reactElement = reactElement; + existingViewItem.mount = true; + existingViewItem.ionPageElement = page || existingViewItem.ionPageElement; + const updatedMatch = + matchComponent(reactElement, routeInfo.pathname, false) || + existingViewItem.routeData?.match || + createDefaultMatch(routeInfo.pathname, reactElement.props); + + existingViewItem.routeData = { + match: updatedMatch, + childProps: reactElement.props, + lastPathname: existingViewItem.routeData?.lastPathname, // Preserve navigation history + }; + return existingViewItem; + } + + this.viewItemCounter++; + const id = `${outletId}-${this.viewItemCounter}`; + const viewItem: ViewItem = { - id: generateId('viewItem'), + id, outletId, ionPageElement: page, reactElement, mount: true, - ionRoute: false, + ionRoute: true, }; if (reactElement.type === IonRoute) { - viewItem.ionRoute = true; viewItem.disableIonPageManagement = reactElement.props.disableIonPageManagement; } + const initialMatch = + matchComponent(reactElement, routeInfo.pathname, true) || + createDefaultMatch(routeInfo.pathname, reactElement.props); + viewItem.routeData = { - match: matchPath({ - pathname: routeInfo.pathname, - componentProps: reactElement.props, - }), + match: initialMatch, childProps: reactElement.props, }; + this.add(viewItem); + return viewItem; - } + }; + + /** + * Renders a ViewLifeCycleManager for the given view item. + * Handles cleanup if the view no longer matches. + * + * - Deactivates view if it no longer matches the current route + * - Wraps the route element in to support nested routing and ensure remounting + * - Adds a unique key to so React Router remounts routes when switching + */ + private renderViewItem = (viewItem: ViewItem, routeInfo: RouteInfo, parentPath?: string) => { + const routePath = viewItem.reactElement.props.path || ''; + let match = matchComponent(viewItem.reactElement, routeInfo.pathname); + + if (!match) { + const indexMatch = resolveIndexRouteMatch(viewItem, routeInfo.pathname, parentPath); + if (indexMatch) { + match = indexMatch; + } + } + + // For parameterized routes, check if this is a navigation to a different path instance + // In that case, we should NOT reuse this view - a new view should be created + const isParameterRoute = routePath.includes(':'); + const previousMatch = viewItem.routeData?.match; + const isSamePath = match?.pathname === previousMatch?.pathname; + + // Flag to indicate this view should not be reused for this different parameterized path + const shouldSkipForDifferentParam = isParameterRoute && match && previousMatch && !isSamePath; + + // Don't deactivate views automatically - let the StackManager handle view lifecycle + // This preserves views in the stack for navigation history like native apps + // Views will be hidden/shown by the StackManager's transition logic instead of being unmounted + + // Special handling for Navigate components - they should unmount after redirecting + const elementComponent = viewItem.reactElement?.props?.element; + const isNavigateComponent = isNavigateElement(elementComponent); + + if (isNavigateComponent) { + // Navigate components should only be mounted when they match + // Once they redirect (no longer match), they should be removed completely + // IMPORTANT: For index routes, we need to check indexMatch too since matchComponent + // may not properly match index routes without explicit parent path context + const indexMatch = viewItem.routeData?.childProps?.index + ? resolveIndexRouteMatch(viewItem, routeInfo.pathname, parentPath) + : null; + const hasValidMatch = match || indexMatch; + + if (!hasValidMatch && viewItem.mount) { + viewItem.mount = false; + // Schedule removal of the Navigate view item after a short delay + // This ensures the redirect completes before removal + setTimeout(() => { + this.remove(viewItem); + }, NAVIGATE_REDIRECT_DELAY_MS); + } + } + + // Components that don't have IonPage elements and no longer match should be cleaned up + // BUT we need to be careful not to remove them if they're part of browser navigation history + // This handles components that perform immediate actions like programmatic navigation + // EXCEPTION: Navigate components should ALWAYS remain mounted until they redirect + // since they need to be rendered to trigger the navigation + if (!match && viewItem.mount && !viewItem.ionPageElement && !isNavigateComponent) { + // Check if this view item should be preserved for browser navigation + // We'll keep it if it was recently active (within the last navigation) + const shouldPreserve = + viewItem.routeData.lastPathname === routeInfo.pathname || + viewItem.routeData.match?.pathname === routeInfo.lastPathname; + + if (!shouldPreserve) { + // This view item doesn't match and doesn't have an IonPage + // It's likely a utility component that performs an action and navigates away + viewItem.mount = false; + // Schedule removal to allow it to be recreated on next navigation + setTimeout(() => { + // Double-check before removing - the view might be needed again + const stillNotNeeded = !viewItem.mount && !viewItem.ionPageElement; + if (stillNotNeeded) { + this.remove(viewItem); + } + }, VIEW_CLEANUP_DELAY_MS); + } else { + // Preserve it but unmount it for now + viewItem.mount = false; + } + } + + // Reactivate view if it matches but was previously deactivated + // Don't reactivate if this is a parameterized route navigating to a different path instance + if (match && !viewItem.mount && !shouldSkipForDifferentParam) { + viewItem.mount = true; + viewItem.routeData.match = match; + } + + // Deactivate wildcard routes and catch-all routes (empty path) when we have specific route matches + // This prevents "Not found" or fallback pages from showing alongside valid routes + if (routePath === '*' || routePath === '') { + // Check if any other view in this outlet has a match for the current route + const hasSpecificMatch = this.getViewItemsForOutlet(viewItem.outletId).some((v) => { + if (v.id === viewItem.id) return false; // Skip self + const vRoutePath = v.reactElement?.props?.path || ''; + if (vRoutePath === '*' || vRoutePath === '') return false; // Skip other wildcard/empty routes + + // Check if this view item would match the current route + const vMatch = v.reactElement ? matchComponent(v.reactElement, routeInfo.pathname) : null; + return !!vMatch; + }); + + if (hasSpecificMatch) { + viewItem.mount = false; + // Also hide the ion-page element immediately to prevent visual overlap + if (viewItem.ionPageElement) { + viewItem.ionPageElement.classList.add('ion-page-hidden'); + viewItem.ionPageElement.setAttribute('aria-hidden', 'true'); + } + } + } + + const routeElement = React.cloneElement(viewItem.reactElement); + const componentElement = routeElement.props.element; + // Don't update match for parameterized routes navigating to different path instances + // This preserves the original match so that findViewItemByPath can correctly skip this view + if (match && viewItem.routeData.match !== match && !shouldSkipForDifferentParam) { + viewItem.routeData.match = match; + } + const routeMatch = shouldSkipForDifferentParam ? viewItem.routeData?.match : match || viewItem.routeData?.match; + + return ( + + {(parentContext) => { + const parentMatches = parentContext?.matches ?? []; + let accumulatedParentParams = parentMatches.reduce>( + (acc, match) => { + return { ...acc, ...match.params }; + }, + {} + ); + + // If parentMatches is empty, try to extract params from view items in other outlets. + // This handles cases where React context propagation doesn't work as expected + // for nested router outlets. + if (parentMatches.length === 0 && Object.keys(accumulatedParentParams).length === 0) { + const allViewItems = this.getAllViewItems(); + for (const otherViewItem of allViewItems) { + // Skip view items from the same outlet + if (otherViewItem.outletId === viewItem.outletId) continue; + + // Check if this view item's route could match the current pathname + const otherMatch = otherViewItem.routeData?.match; + if (otherMatch && otherMatch.params && Object.keys(otherMatch.params).length > 0) { + // Check if the current pathname starts with this view item's matched pathname + const matchedPathname = otherMatch.pathnameBase || otherMatch.pathname; + if (matchedPathname && routeInfo.pathname.startsWith(matchedPathname)) { + accumulatedParentParams = { ...accumulatedParentParams, ...otherMatch.params }; + } + } + } + } + + const combinedParams = { + ...accumulatedParentParams, + ...(routeMatch?.params ?? {}), + }; + + // For relative route paths, we need to compute an absolute pathnameBase + // by combining the parent's pathnameBase with the matched portion + let absolutePathnameBase = routeMatch?.pathnameBase || routeInfo.pathname; + const routePath = routeElement.props.path; + const isRelativePath = routePath && !routePath.startsWith('/'); + const isIndexRoute = !!routeElement.props.index; + + if (isRelativePath || isIndexRoute) { + // Get the parent's pathnameBase to build the absolute path + const parentPathnameBase = + parentMatches.length > 0 ? parentMatches[parentMatches.length - 1].pathnameBase : '/'; + + // For relative paths, the matchPath returns a relative pathnameBase + // We need to make it absolute by prepending the parent's base + if (routeMatch?.pathnameBase && isRelativePath) { + // Strip leading slash if present in the relative match + const relativeBase = routeMatch.pathnameBase.startsWith('/') + ? routeMatch.pathnameBase.slice(1) + : routeMatch.pathnameBase; + + absolutePathnameBase = + parentPathnameBase === '/' ? `/${relativeBase}` : `${parentPathnameBase}/${relativeBase}`; + } else if (isIndexRoute) { + // Index routes should use the parent's base as their base + absolutePathnameBase = parentPathnameBase; + } + } + + const contextMatches = [ + ...parentMatches, + { + params: combinedParams, + pathname: routeMatch?.pathname || routeInfo.pathname, + pathnameBase: absolutePathnameBase, + route: { + id: viewItem.id, + path: routeElement.props.path, + element: componentElement, + index: !!routeElement.props.index, + caseSensitive: routeElement.props.caseSensitive, + hasErrorBoundary: false, + }, + }, + ]; + + const routeContextValue = parentContext + ? { + ...parentContext, + matches: contextMatches, + } + : { + outlet: null, + matches: contextMatches, + isDataRoute: false, + }; - getChildrenToRender(outletId: string, ionRouterOutlet: React.ReactElement, routeInfo: RouteInfo) { + return ( + this.remove(viewItem)} + > + {componentElement} + + ); + }} + + ); + }; + + /** + * Re-renders all active view items for the specified outlet. + * Ensures React elements are updated with the latest match. + * + * 1. Iterates through children of IonRouterOutlet + * 2. Updates each matching viewItem with the current child React element + * (important for updating props or changes to elements) + * 3. Returns a list of React components that will be rendered inside the outlet + * Each view is wrapped in to manage lifecycle and rendering + */ + getChildrenToRender = (outletId: string, ionRouterOutlet: React.ReactElement, routeInfo: RouteInfo) => { const viewItems = this.getViewItemsForOutlet(outletId); - // Sync latest routes with viewItems + // Determine parentPath for nested outlets to properly evaluate index routes + let parentPath: string | undefined = undefined; + try { + // Only attempt parent path computation for non-root outlets + if (outletId !== 'routerOutlet') { + const routeChildren = extractRouteChildren(ionRouterOutlet.props.children); + const { hasRelativeRoutes, hasIndexRoute, hasWildcardRoute } = analyzeRouteChildren(routeChildren); + + if (hasRelativeRoutes || hasIndexRoute) { + const result = computeParentPath({ + currentPathname: routeInfo.pathname, + outletMountPath: undefined, + routeChildren, + hasRelativeRoutes, + hasIndexRoute, + hasWildcardRoute, + }); + parentPath = result.parentPath; + } + } + } catch (e) { + // Non-fatal: if we fail to compute parentPath, fall back to previous behavior + } + + // Sync child elements with stored viewItems (e.g. to reflect new props) React.Children.forEach(ionRouterOutlet.props.children, (child: React.ReactElement) => { - const viewItem = viewItems.find((v) => { - return matchComponent(child, v.routeData.childProps.path || v.routeData.childProps.from); - }); - if (viewItem) { - viewItem.reactElement = child; + // Ensure the child is a valid React element since we + // might have whitespace strings or other non-element children + if (React.isValidElement(child)) { + // Find view item by exact path match to avoid wildcard routes overwriting specific routes + const childPath = (child.props as any).path; + const viewItem = viewItems.find((v) => { + const viewItemPath = v.reactElement?.props?.path; + // Only update if paths match exactly (prevents wildcard routes from overwriting specific routes) + return viewItemPath === childPath; + }); + if (viewItem) { + viewItem.reactElement = child; + } } }); - const children = viewItems.map((viewItem) => { - let clonedChild; - if (viewItem.ionRoute && !viewItem.disableIonPageManagement) { - clonedChild = ( - this.remove(viewItem)} - > - {React.cloneElement(viewItem.reactElement, { - computedMatch: viewItem.routeData.match, - })} - - ); - } else { - const match = matchComponent(viewItem.reactElement, routeInfo.pathname); - clonedChild = ( - this.remove(viewItem)} - > - {React.cloneElement(viewItem.reactElement, { - computedMatch: viewItem.routeData.match, - })} - - ); - - if (!match && viewItem.routeData.match) { - viewItem.routeData.match = undefined; - viewItem.mount = false; + // Filter out duplicate view items by ID (but keep all mounted items) + const uniqueViewItems = viewItems.filter((viewItem, index, array) => { + // Remove duplicates by ID (keep first occurrence) + const isFirstOccurrence = array.findIndex((v) => v.id === viewItem.id) === index; + return isFirstOccurrence; + }); + + // Filter out unmounted Navigate components to prevent them from being rendered + // and triggering unwanted redirects + const renderableViewItems = uniqueViewItems.filter((viewItem) => { + const elementComponent = viewItem.reactElement?.props?.element; + const isNavigateComponent = isNavigateElement(elementComponent); + + // Exclude unmounted Navigate components from rendering + if (isNavigateComponent && !viewItem.mount) { + return false; + } + + // Filter out views that are unmounted, have no ionPageElement, and don't match the current route. + // These are "stale" views from previous routes that should not be rendered. + // Views WITH ionPageElement are handled by the normal lifecycle events. + // Views that MATCH the current route should be kept (they might be transitioning). + if (!viewItem.mount && !viewItem.ionPageElement) { + // Check if this view's route path matches the current pathname + const viewRoutePath = viewItem.reactElement?.props?.path as string | undefined; + if (viewRoutePath) { + // First try exact match using matchComponent + const routeMatch = matchComponent(viewItem.reactElement, routeInfo.pathname); + if (routeMatch) { + // View matches current route, keep it + return true; + } + + // For parent routes (like /multiple-tabs or /routing), check if current pathname + // starts with this route's path. This handles views with IonSplitPane/IonTabs + // that don't have IonPage but should remain mounted while navigating within their children. + const normalizedViewPath = normalizePathnameForComparison(viewRoutePath.replace(/\/?\*$/, '')); // Remove trailing wildcard + const normalizedCurrentPath = normalizePathnameForComparison(routeInfo.pathname); + + // Check if current pathname is within this view's route hierarchy + const isWithinRouteHierarchy = + normalizedCurrentPath === normalizedViewPath || normalizedCurrentPath.startsWith(normalizedViewPath + '/'); + + if (!isWithinRouteHierarchy) { + // View is outside current route hierarchy, remove it + setTimeout(() => { + this.remove(viewItem); + }, 0); + return false; + } } } - return clonedChild; + return true; }); - return children; - } - findViewItemByRouteInfo(routeInfo: RouteInfo, outletId?: string, updateMatch?: boolean) { + const renderedItems = renderableViewItems.map((viewItem) => this.renderViewItem(viewItem, routeInfo, parentPath)); + return renderedItems; + }; + + /** + * Finds a view item matching the current route, optionally updating its match state. + */ + findViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: string, updateMatch?: boolean) => { const { viewItem, match } = this.findViewItemByPath(routeInfo.pathname, outletId); const shouldUpdateMatch = updateMatch === undefined || updateMatch === true; if (shouldUpdateMatch && viewItem && match) { viewItem.routeData.match = match; } return viewItem; - } + }; - findLeavingViewItemByRouteInfo(routeInfo: RouteInfo, outletId?: string, mustBeIonRoute = true) { - const { viewItem } = this.findViewItemByPath(routeInfo.lastPathname!, outletId, mustBeIonRoute); + /** + * Finds the view item that was previously active before a route change. + */ + findLeavingViewItemByRouteInfo = (routeInfo: RouteInfo, outletId?: string, mustBeIonRoute = true) => { + // If the lastPathname is not set, we cannot find a leaving view item + if (!routeInfo.lastPathname) { + return undefined; + } + + const { viewItem } = this.findViewItemByPath(routeInfo.lastPathname, outletId, mustBeIonRoute); return viewItem; - } + }; - findViewItemByPathname(pathname: string, outletId?: string) { + /** + * Finds a view item by pathname only, used in simpler queries. + */ + findViewItemByPathname = (pathname: string, outletId?: string) => { const { viewItem } = this.findViewItemByPath(pathname, outletId); return viewItem; - } + }; /** - * Returns the matching view item and the match result for a given pathname. + * Core function that matches a given pathname against all view items. + * Returns both the matched view item and match metadata. */ - private findViewItemByPath(pathname: string, outletId?: string, mustBeIonRoute?: boolean) { + private findViewItemByPath(pathname: string, outletId?: string, mustBeIonRoute?: boolean, allowDefaultMatch = true) { let viewItem: ViewItem | undefined; - let match: ReturnType | undefined; + let match: PathMatch | null = null; let viewStack: ViewItem[]; if (outletId) { - viewStack = this.getViewItemsForOutlet(outletId); + viewStack = sortViewsBySpecificity(this.getViewItemsForOutlet(outletId)); viewStack.some(matchView); - if (!viewItem) { - viewStack.some(matchDefaultRoute); - } + if (!viewItem && allowDefaultMatch) viewStack.some(matchDefaultRoute); } else { - const viewItems = this.getAllViewItems(); + const viewItems = sortViewsBySpecificity(this.getAllViewItems()); viewItems.some(matchView); - if (!viewItem) { - viewItems.some(matchDefaultRoute); - } + if (!viewItem && allowDefaultMatch) viewItems.some(matchDefaultRoute); } + // If we still have not found a view item for this outlet, try to find a matching + // view item across all outlets and adopt it into the current outlet. This helps + // recover when an outlet remounts and receives a new id, leaving views associated + // with the previous outlet id. + // Do not adopt across outlets; if we didn't find a view for this outlet, + // defer to route matching to create a new one. + return { viewItem, match }; + /** + * Matches a route path with dynamic parameters (e.g. /tabs/:id) + */ function matchView(v: ViewItem) { - if (mustBeIonRoute && !v.ionRoute) { - return false; + if (mustBeIonRoute && !v.ionRoute) return false; + + const viewItemPath = v.routeData.childProps.path || ''; + const isIndexRoute = !!v.routeData.childProps.index; + const previousMatch = v.routeData?.match; + const result = v.reactElement ? matchComponent(v.reactElement, pathname) : null; + + if (!result) { + const indexMatch = resolveIndexRouteMatch(v, pathname, undefined); + if (indexMatch) { + match = indexMatch; + viewItem = v; + return true; + } } - match = matchPath({ - pathname, - componentProps: v.routeData.childProps, - }); + if (result) { + const hasParams = result.params && Object.keys(result.params).length > 0; + const isSamePath = result.pathname === previousMatch?.pathname; + const isWildcardRoute = viewItemPath.includes('*'); + const isParameterRoute = viewItemPath.includes(':'); + + // Don't allow view items with undefined paths to match specific routes + // This prevents broken index route view items from interfering with navigation + if (!viewItemPath && !isIndexRoute && pathname !== '/' && pathname !== '') { + return false; + } + + // For parameterized routes, check if we should reuse the view item. + // Wildcard routes (e.g., user/:userId/*) compare pathnameBase to allow + // child path changes while preserving the parent view. + if (isParameterRoute && !isSamePath) { + if (isWildcardRoute) { + const isSameBase = result.pathnameBase === previousMatch?.pathnameBase; + if (isSameBase) { + match = result; + viewItem = v; + return true; + } + } + return false; + } - if (match) { - /** - * Even though we have a match from react-router, we do not know if the match - * is for this specific view item. - * - * To validate this, we need to check if the path and url match the view item's route data. - */ - const hasParameter = match.path.includes(':'); - if (!hasParameter || (hasParameter && match.url === v.routeData?.match?.url)) { + // For routes without params, or when navigating to the exact same path, + // or when there's no previous match, reuse the view item + if (!hasParams || isSamePath || !previousMatch) { + match = result; + viewItem = v; + return true; + } + + // For wildcard routes (without params), only reuse if the pathname exactly matches + if (isWildcardRoute && isSamePath) { + match = result; viewItem = v; return true; } } + return false; } - function matchDefaultRoute(v: ViewItem) { - // try to find a route that doesn't have a path or from prop, that will be our default route - if (!v.routeData.childProps.path && !v.routeData.childProps.from) { + /** + * Matches a view with no path prop (default fallback route) or index route. + */ + function matchDefaultRoute(v: ViewItem): boolean { + const childProps = v.routeData.childProps; + + const isDefaultRoute = childProps.path === undefined || childProps.path === ''; + const isIndexRoute = !!childProps.index; + + if (isIndexRoute) { + const indexMatch = resolveIndexRouteMatch(v, pathname, undefined); + if (indexMatch) { + match = indexMatch; + viewItem = v; + return true; + } + return false; + } + + if (isDefaultRoute) { match = { - path: pathname, - url: pathname, - isExact: true, params: {}, + pathname, + pathnameBase: pathname === '' ? '/' : pathname, + pattern: { + path: '', + caseSensitive: childProps.caseSensitive ?? false, + end: true, + }, }; viewItem = v; return true; } + return false; } } + + /** + * Clean up old, unmounted view items to prevent memory leaks + */ + private cleanupStaleViewItems = (outletId: string) => { + const viewItems = this.getViewItemsForOutlet(outletId); + + // Keep only the most recent mounted views and a few unmounted ones for history + const maxUnmountedItems = 3; + const unmountedItems = viewItems.filter((v) => !v.mount); + + if (unmountedItems.length > maxUnmountedItems) { + // Remove oldest unmounted items + const itemsToRemove = unmountedItems.slice(0, unmountedItems.length - maxUnmountedItems); + itemsToRemove.forEach((item) => { + this.remove(item); + }); + } + }; + + /** + * Override add to prevent duplicate view items with the same ID in the same outlet + * But allow multiple view items for the same route path (for navigation history) + */ + add = (viewItem: ViewItem) => { + const existingViewItem = this.getViewItemsForOutlet(viewItem.outletId).find((v) => v.id === viewItem.id); + + if (existingViewItem) { + return; + } + + super.add(viewItem); + + this.cleanupStaleViewItems(viewItem.outletId); + }; + + /** + * Override remove + */ + remove = (viewItem: ViewItem) => { + super.remove(viewItem); + }; } -function matchComponent(node: React.ReactElement, pathname: string) { - return matchPath({ - pathname, - componentProps: node.props, +/** + * Utility to apply matchPath to a React element and return its match state. + */ +function matchComponent(node: React.ReactElement, pathname: string, allowFallback = false) { + const routeProps = node?.props ?? {}; + const routePath: string | undefined = routeProps.path; + const pathnameToMatch = derivePathnameToMatch(pathname, routePath); + + const match = matchPath({ + pathname: pathnameToMatch, + componentProps: routeProps, }); + + if (match || !allowFallback) { + return match; + } + + const isIndexRoute = !!routeProps.index; + + if (isIndexRoute) { + return createDefaultMatch(pathname, routeProps); + } + + if (!routePath || routePath === '') { + return createDefaultMatch(pathname, routeProps); + } + + return null; } diff --git a/packages/react-router/src/ReactRouter/StackManager.tsx b/packages/react-router/src/ReactRouter/StackManager.tsx index 708de651391..4ce73c561b0 100644 --- a/packages/react-router/src/ReactRouter/StackManager.tsx +++ b/packages/react-router/src/ReactRouter/StackManager.tsx @@ -1,24 +1,62 @@ +/** + * `StackManager` is responsible for managing page transitions, keeping track + * of views (pages), and ensuring that navigation behaves like native apps — + * particularly with animations and swipe gestures. + */ + import type { RouteInfo, StackContextState, ViewItem } from '@ionic/react'; import { RouteManagerContext, StackContext, generateId, getConfig } from '@ionic/react'; import React from 'react'; +import { Route } from 'react-router-dom'; import { clonePageElement } from './clonePageElement'; -import { matchPath } from './utils/matchPath'; - -// TODO(FW-2959): types +import { analyzeRouteChildren, computeCommonPrefix, computeParentPath } from './utils/computeParentPath'; +import { derivePathnameToMatch, matchPath } from './utils/pathMatching'; +import { stripTrailingSlash } from './utils/pathNormalization'; +import { extractRouteChildren, getRoutesChildren, isNavigateElement } from './utils/routeElements'; + +/** + * Delay in milliseconds before unmounting a view after a transition completes. + * This ensures the page transition animation finishes before the view is removed. + */ +const VIEW_UNMOUNT_DELAY_MS = 250; + +/** + * Delay in milliseconds to wait for an IonPage element to be mounted before + * proceeding with a page transition. + */ +const ION_PAGE_WAIT_TIMEOUT_MS = 50; interface StackManagerProps { routeInfo: RouteInfo; + id?: string; } -// eslint-disable-next-line @typescript-eslint/no-empty-interface -interface StackManagerState {} - const isViewVisible = (el: HTMLElement) => !el.classList.contains('ion-page-invisible') && !el.classList.contains('ion-page-hidden'); -export class StackManager extends React.PureComponent { - id: string; +/** + * Hides an ion-page element by adding hidden class and aria attribute. + */ +const hideIonPageElement = (element: HTMLElement | undefined): void => { + if (element) { + element.classList.add('ion-page-hidden'); + element.setAttribute('aria-hidden', 'true'); + } +}; + +/** + * Shows an ion-page element by removing hidden class and aria attribute. + */ +const showIonPageElement = (element: HTMLElement | undefined): void => { + if (element) { + element.classList.remove('ion-page-hidden'); + element.removeAttribute('aria-hidden'); + } +}; + +export class StackManager extends React.PureComponent { + id: string; // Unique id for the router outlet aka outletId context!: React.ContextType; ionRouterOutlet?: React.ReactElement; routerOutletElement: HTMLIonRouterOutletElement | undefined; @@ -32,17 +70,416 @@ export class StackManager extends React.PureComponent; + private outOfScopeUnmountTimeout?: ReturnType; + /** + * Track the last transition's entering and leaving view IDs to prevent + * duplicate transitions during rapid navigation (e.g., Navigate redirects) + */ + private lastTransition?: { enteringId: string; leavingId?: string }; constructor(props: StackManagerProps) { super(props); this.registerIonPage = this.registerIonPage.bind(this); this.transitionPage = this.transitionPage.bind(this); this.handlePageTransition = this.handlePageTransition.bind(this); - this.id = generateId('routerOutlet'); + this.id = props.id || `routerOutlet-${generateId('routerOutlet')}`; this.prevProps = undefined; this.skipTransition = false; } + private outletMountPath: string | undefined = undefined; + + /** + * Determines the parent path that was matched to reach this outlet. + * This helps with nested routing in React Router 6. + * + * The algorithm finds the shortest parent path where a route matches the remaining path. + * Priority: specific routes > wildcard routes > index routes (only at mount point) + */ + private getParentPath(): string | undefined { + const currentPathname = this.props.routeInfo.pathname; + + // If this outlet previously established a mount path and the current + // pathname is outside of that scope, do not attempt to re-compute a new + // parent path. This prevents out-of-scope outlets from "adopting" + // unrelated routes (e.g., matching their index route under /overlays). + if (this.outletMountPath && !currentPathname.startsWith(this.outletMountPath)) { + return undefined; + } + + // If this is a nested outlet (has an explicit ID like "main"), + // we need to figure out what part of the path was already matched + if (this.id !== 'routerOutlet' && this.ionRouterOutlet) { + const routeChildren = extractRouteChildren(this.ionRouterOutlet.props.children); + const { hasRelativeRoutes, hasIndexRoute, hasWildcardRoute } = analyzeRouteChildren(routeChildren); + + const result = computeParentPath({ + currentPathname, + outletMountPath: this.outletMountPath, + routeChildren, + hasRelativeRoutes, + hasIndexRoute, + hasWildcardRoute, + }); + + // Update the outlet mount path if it was set + if (result.outletMountPath && !this.outletMountPath) { + this.outletMountPath = result.outletMountPath; + } + + return result.parentPath; + } + return this.outletMountPath; + } + + /** + * Finds the entering and leaving view items for a route transition, + * handling special redirect cases. + */ + private findViewItems(routeInfo: RouteInfo): { + enteringViewItem: ViewItem | undefined; + leavingViewItem: ViewItem | undefined; + } { + const enteringViewItem = this.context.findViewItemByRouteInfo(routeInfo, this.id); + let leavingViewItem = this.context.findLeavingViewItemByRouteInfo(routeInfo, this.id); + + // If we don't have a leaving view item, but the route info indicates + // that the user has routed from a previous path, then the leaving view + // can be found by the last known pathname. + if (!leavingViewItem && routeInfo.prevRouteLastPathname) { + leavingViewItem = this.context.findViewItemByPathname(routeInfo.prevRouteLastPathname, this.id); + } + + // Special case for redirects: When a redirect happens inside a nested route, + // the entering and leaving view might be the same (the container route like tabs/*). + // In this case, we need to look at prevRouteLastPathname to find the actual + // view we're transitioning away from. + if ( + enteringViewItem && + leavingViewItem && + enteringViewItem === leavingViewItem && + routeInfo.routeAction === 'replace' && + routeInfo.prevRouteLastPathname + ) { + const actualLeavingView = this.context.findViewItemByPathname(routeInfo.prevRouteLastPathname, this.id); + if (actualLeavingView && actualLeavingView !== enteringViewItem) { + leavingViewItem = actualLeavingView; + } + } + + // Also check if we're in a redirect scenario where entering and leaving are different + // but we still need to handle the actual previous view. + if ( + enteringViewItem && + !leavingViewItem && + routeInfo.routeAction === 'replace' && + routeInfo.prevRouteLastPathname + ) { + const actualLeavingView = this.context.findViewItemByPathname(routeInfo.prevRouteLastPathname, this.id); + if (actualLeavingView && actualLeavingView !== enteringViewItem) { + leavingViewItem = actualLeavingView; + } + } + + return { enteringViewItem, leavingViewItem }; + } + + /** + * Determines if the leaving view item should be unmounted after a transition. + */ + private shouldUnmountLeavingView( + routeInfo: RouteInfo, + enteringViewItem: ViewItem | undefined, + leavingViewItem: ViewItem | undefined + ): boolean { + if (!leavingViewItem) { + return false; + } + + if (routeInfo.routeAction === 'replace') { + return true; + } + + const isForwardPush = routeInfo.routeAction === 'push' && (routeInfo as any).routeDirection === 'forward'; + if (!isForwardPush && routeInfo.routeDirection !== 'none' && enteringViewItem !== leavingViewItem) { + return true; + } + + return false; + } + + /** + * Handles the case when the outlet is out of scope (current route is outside mount path). + * Returns true if the transition should be aborted. + */ + private handleOutOfScopeOutlet(routeInfo: RouteInfo): boolean { + if (!this.outletMountPath || routeInfo.pathname.startsWith(this.outletMountPath)) { + return false; + } + + // Clear any pending unmount timeout to avoid conflicts + if (this.outOfScopeUnmountTimeout) { + clearTimeout(this.outOfScopeUnmountTimeout); + this.outOfScopeUnmountTimeout = undefined; + } + + // When an outlet is out of scope, unmount its views immediately + const allViewsInOutlet = this.context.getViewItemsForOutlet ? this.context.getViewItemsForOutlet(this.id) : []; + + // Unmount and remove all views in this outlet immediately to avoid leftover content + allViewsInOutlet.forEach((viewItem) => { + hideIonPageElement(viewItem.ionPageElement); + this.context.unMountViewItem(viewItem); + }); + + this.forceUpdate(); + return true; + } + + /** + * Handles the case when this is a nested outlet with relative routes but no valid parent path. + * Returns true if the transition should be aborted. + */ + private handleOutOfContextNestedOutlet( + parentPath: string | undefined, + leavingViewItem: ViewItem | undefined + ): boolean { + if (this.id === 'routerOutlet' || parentPath !== undefined || !this.ionRouterOutlet) { + return false; + } + + const routesChildren = + getRoutesChildren(this.ionRouterOutlet.props.children) ?? this.ionRouterOutlet.props.children; + const routeChildren = React.Children.toArray(routesChildren).filter( + (child): child is React.ReactElement => React.isValidElement(child) && child.type === Route + ); + + const hasRelativeRoutes = routeChildren.some((route) => { + const path = route.props.path; + return path && !path.startsWith('/') && path !== '*'; + }); + + if (hasRelativeRoutes) { + // Hide any visible views in this outlet since it's out of scope + hideIonPageElement(leavingViewItem?.ionPageElement); + if (leavingViewItem) { + leavingViewItem.mount = false; + } + this.forceUpdate(); + return true; + } + + return false; + } + + /** + * Handles the case when a nested outlet has no matching route. + * Returns true if the transition should be aborted. + */ + private handleNoMatchingRoute( + enteringRoute: React.ReactElement | undefined, + enteringViewItem: ViewItem | undefined, + leavingViewItem: ViewItem | undefined + ): boolean { + if (this.id === 'routerOutlet' || enteringRoute || enteringViewItem) { + return false; + } + + // Hide any visible views in this outlet since it has no matching route + hideIonPageElement(leavingViewItem?.ionPageElement); + if (leavingViewItem) { + leavingViewItem.mount = false; + } + this.forceUpdate(); + return true; + } + + /** + * Handles the transition when entering view item has an ion-page element ready. + */ + private handleReadyEnteringView( + routeInfo: RouteInfo, + enteringViewItem: ViewItem, + leavingViewItem: ViewItem | undefined, + shouldUnmountLeavingViewItem: boolean + ): void { + // Ensure the entering view is not hidden from previous navigations + showIonPageElement(enteringViewItem.ionPageElement); + + // Handle same view item case (e.g., parameterized route changes) + if (enteringViewItem === leavingViewItem) { + const routePath = enteringViewItem.reactElement?.props?.path as string | undefined; + const isParameterizedRoute = routePath ? routePath.includes(':') : false; + + if (isParameterizedRoute) { + // Refresh match metadata so the component receives updated params + const updatedMatch = matchComponent(enteringViewItem.reactElement, routeInfo.pathname, true); + if (updatedMatch) { + enteringViewItem.routeData.match = updatedMatch; + } + + const enteringEl = enteringViewItem.ionPageElement; + if (enteringEl) { + enteringEl.classList.remove('ion-page-hidden', 'ion-page-invisible'); + enteringEl.removeAttribute('aria-hidden'); + } + + this.forceUpdate(); + return; + } + } + + // Try to find leaving view using prev route info if still not found + if (!leavingViewItem && this.props.routeInfo.prevRouteLastPathname) { + leavingViewItem = this.context.findViewItemByPathname(this.props.routeInfo.prevRouteLastPathname, this.id); + } + + // Skip transition if entering view is visible and leaving view is not + if ( + enteringViewItem.ionPageElement && + isViewVisible(enteringViewItem.ionPageElement) && + leavingViewItem !== undefined && + leavingViewItem.ionPageElement && + !isViewVisible(leavingViewItem.ionPageElement) + ) { + return; + } + + // Check for duplicate transition + const currentTransition = { + enteringId: enteringViewItem.id, + leavingId: leavingViewItem?.id, + }; + + if ( + leavingViewItem && + this.lastTransition && + this.lastTransition.leavingId && + this.lastTransition.enteringId === currentTransition.enteringId && + this.lastTransition.leavingId === currentTransition.leavingId + ) { + return; + } + + this.lastTransition = currentTransition; + this.transitionPage(routeInfo, enteringViewItem, leavingViewItem); + + // Handle unmounting the leaving view + if (shouldUnmountLeavingViewItem && leavingViewItem && enteringViewItem !== leavingViewItem) { + leavingViewItem.mount = false; + this.handleLeavingViewUnmount(routeInfo, enteringViewItem, leavingViewItem); + } + } + + /** + * Handles the delayed unmount of the leaving view item after a replace action. + */ + private handleLeavingViewUnmount(routeInfo: RouteInfo, enteringViewItem: ViewItem, leavingViewItem: ViewItem): void { + if (routeInfo.routeAction !== 'replace' || !leavingViewItem.ionPageElement) { + return; + } + + // Check if we should skip removal for nested outlet redirects + const enteringRoutePath = enteringViewItem.reactElement?.props?.path as string | undefined; + const leavingRoutePath = leavingViewItem.reactElement?.props?.path as string | undefined; + const isEnteringContainerRoute = enteringRoutePath && enteringRoutePath.endsWith('/*'); + const isLeavingSpecificRoute = + leavingRoutePath && + leavingRoutePath !== '' && + leavingRoutePath !== '*' && + !leavingRoutePath.endsWith('/*') && + !leavingViewItem.reactElement?.props?.index; + + // Skip removal only for container-to-container transitions + if (isEnteringContainerRoute && !isLeavingSpecificRoute) { + return; + } + + const viewToUnmount = leavingViewItem; + setTimeout(() => { + this.context.unMountViewItem(viewToUnmount); + }, VIEW_UNMOUNT_DELAY_MS); + } + + /** + * Handles the case when entering view has no ion-page element yet (waiting for render). + */ + private handleWaitingForIonPage( + routeInfo: RouteInfo, + enteringViewItem: ViewItem, + leavingViewItem: ViewItem | undefined, + shouldUnmountLeavingViewItem: boolean + ): void { + const enteringRouteElement = enteringViewItem.reactElement?.props?.element; + + // Handle Navigate components (they never render an IonPage) + if (isNavigateElement(enteringRouteElement)) { + this.waitingForIonPage = false; + if (this.ionPageWaitTimeout) { + clearTimeout(this.ionPageWaitTimeout); + this.ionPageWaitTimeout = undefined; + } + this.pendingPageTransition = false; + + // Hide the leaving view immediately for Navigate redirects + hideIonPageElement(leavingViewItem?.ionPageElement); + + // Don't unmount if entering and leaving are the same view item + if (shouldUnmountLeavingViewItem && leavingViewItem && enteringViewItem !== leavingViewItem) { + leavingViewItem.mount = false; + } + + this.forceUpdate(); + return; + } + + // Hide leaving view while we wait for the entering view's IonPage to mount + hideIonPageElement(leavingViewItem?.ionPageElement); + + this.waitingForIonPage = true; + + if (this.ionPageWaitTimeout) { + clearTimeout(this.ionPageWaitTimeout); + } + + this.ionPageWaitTimeout = setTimeout(() => { + this.ionPageWaitTimeout = undefined; + + if (!this.waitingForIonPage) { + return; + } + this.waitingForIonPage = false; + + const latestEnteringView = this.context.findViewItemByRouteInfo(routeInfo, this.id) ?? enteringViewItem; + const latestLeavingView = this.context.findLeavingViewItemByRouteInfo(routeInfo, this.id) ?? leavingViewItem; + + if (latestEnteringView?.ionPageElement) { + this.transitionPage(routeInfo, latestEnteringView, latestLeavingView ?? undefined); + + if (shouldUnmountLeavingViewItem && latestLeavingView && latestEnteringView !== latestLeavingView) { + latestLeavingView.mount = false; + } + + this.forceUpdate(); + } + }, ION_PAGE_WAIT_TIMEOUT_MS); + + this.forceUpdate(); + } + + /** + * Gets the route info to use for finding views during swipe-to-go-back gestures. + * This pattern is used in multiple places in setupRouterOutlet. + */ + private getSwipeBackRouteInfo(): RouteInfo { + const { routeInfo } = this.props; + return this.prevProps && this.prevProps.routeInfo.pathname === routeInfo.pushedByRoute + ? this.prevProps.routeInfo + : ({ pathname: routeInfo.pushedByRoute || '' } as RouteInfo); + } + componentDidMount() { if (this.clearOutletTimeout) { /** @@ -76,121 +513,138 @@ export class StackManager extends React.PureComponent { + hideIonPageElement(viewItem.ionPageElement); + }); + this.clearOutletTimeout = this.context.clearOutlet(this.id); } + /** + * Sets the transition between pages within this router outlet. + * This function determines the entering and leaving views based on the + * provided route information and triggers the appropriate animation. + * It also handles scenarios like initial loads, back navigation, and + * navigation to the same view with different parameters. + * + * @param routeInfo It contains info about the current route, + * the previous route, and the action taken (e.g., push, replace). + * + * @returns A promise that resolves when the transition is complete. + * If no transition is needed or if the router outlet isn't ready, + * the Promise may resolve immediately. + */ async handlePageTransition(routeInfo: RouteInfo) { + // Wait for router outlet to mount if (!this.routerOutletElement || !this.routerOutletElement.commit) { - /** - * The route outlet has not mounted yet. We need to wait for it to render - * before we can transition the page. - * - * Set a flag to indicate that we should transition the page after - * the component has updated. - */ this.pendingPageTransition = true; - } else { - let enteringViewItem = this.context.findViewItemByRouteInfo(routeInfo, this.id); - let leavingViewItem = this.context.findLeavingViewItemByRouteInfo(routeInfo, this.id); + return; + } - if (!leavingViewItem && routeInfo.prevRouteLastPathname) { - leavingViewItem = this.context.findViewItemByPathname(routeInfo.prevRouteLastPathname, this.id); - } + // Find entering and leaving view items + const viewItems = this.findViewItems(routeInfo); + let enteringViewItem = viewItems.enteringViewItem; + const leavingViewItem = viewItems.leavingViewItem; + const shouldUnmountLeavingViewItem = this.shouldUnmountLeavingView(routeInfo, enteringViewItem, leavingViewItem); - // Check if leavingViewItem should be unmounted - if (leavingViewItem) { - if (routeInfo.routeAction === 'replace') { - leavingViewItem.mount = false; - } else if (!(routeInfo.routeAction === 'push' && routeInfo.routeDirection === 'forward')) { - if (routeInfo.routeDirection !== 'none' && enteringViewItem !== leavingViewItem) { - leavingViewItem.mount = false; - } - } else if (routeInfo.routeOptions?.unmount) { - leavingViewItem.mount = false; - } - } + // Get parent path for nested outlets + const parentPath = this.getParentPath(); - const enteringRoute = matchRoute(this.ionRouterOutlet?.props.children, routeInfo) as React.ReactElement; + // Handle out-of-scope outlet (route outside mount path) + if (this.handleOutOfScopeOutlet(routeInfo)) { + return; + } - if (enteringViewItem) { - enteringViewItem.reactElement = enteringRoute; - } else if (enteringRoute) { - enteringViewItem = this.context.createViewItem(this.id, enteringRoute, routeInfo); - this.context.addViewItem(enteringViewItem); - } + // Clear any pending out-of-scope unmount timeout + if (this.outOfScopeUnmountTimeout) { + clearTimeout(this.outOfScopeUnmountTimeout); + this.outOfScopeUnmountTimeout = undefined; + } - if (enteringViewItem && enteringViewItem.ionPageElement) { - /** - * If the entering view item is the same as the leaving view item, - * then we don't need to transition. - */ - if (enteringViewItem === leavingViewItem) { - /** - * If the entering view item is the same as the leaving view item, - * we are either transitioning using parameterized routes to the same view - * or a parent router outlet is re-rendering as a result of React props changing. - * - * If the route data does not match the current path, the parent router outlet - * is attempting to transition and we cancel the operation. - */ - if (enteringViewItem.routeData.match.url !== routeInfo.pathname) { - return; - } - } + // Handle nested outlet with relative routes but no valid parent path + if (this.handleOutOfContextNestedOutlet(parentPath, leavingViewItem)) { + return; + } - /** - * If there isn't a leaving view item, but the route info indicates - * that the user has routed from a previous path, then we need - * to find the leaving view item to transition between. - */ - if (!leavingViewItem && this.props.routeInfo.prevRouteLastPathname) { - leavingViewItem = this.context.findViewItemByPathname(this.props.routeInfo.prevRouteLastPathname, this.id); - } + // Find the matching route element + const enteringRoute = findRouteByRouteInfo( + this.ionRouterOutlet?.props.children, + routeInfo, + parentPath + ) as React.ReactElement; - /** - * If the entering view is already visible and the leaving view is not, the transition does not need to occur. - */ - if ( - isViewVisible(enteringViewItem.ionPageElement) && - leavingViewItem !== undefined && - !isViewVisible(leavingViewItem.ionPageElement!) - ) { - return; - } + // Handle nested outlet with no matching route + if (this.handleNoMatchingRoute(enteringRoute, enteringViewItem, leavingViewItem)) { + return; + } - /** - * The view should only be transitioned in the following cases: - * 1. Performing a replace or pop action, such as a swipe to go back gesture - * to animation the leaving view off the screen. - * - * 2. Navigating between top-level router outlets, such as /page-1 to /page-2; - * or navigating within a nested outlet, such as /tabs/tab-1 to /tabs/tab-2. - * - * 3. The entering view is an ion-router-outlet containing a page - * matching the current route and that hasn't already transitioned in. - * - * This should only happen when navigating directly to a nested router outlet - * route or on an initial page load (i.e. refreshing). In cases when loading - * /tabs/tab-1, we need to transition the /tabs page element into the view. - */ - this.transitionPage(routeInfo, enteringViewItem, leavingViewItem); - } else if (leavingViewItem && !enteringRoute && !enteringViewItem) { - // If we have a leavingView but no entering view/route, we are probably leaving to - // another outlet, so hide this leavingView. We do it in a timeout to give time for a - // transition to finish. - // setTimeout(() => { - if (leavingViewItem.ionPageElement) { - leavingViewItem.ionPageElement.classList.add('ion-page-hidden'); - leavingViewItem.ionPageElement.setAttribute('aria-hidden', 'true'); - } - // }, 250); + // Create or update the entering view item + if (enteringViewItem && enteringRoute) { + enteringViewItem.reactElement = enteringRoute; + } else if (enteringRoute) { + enteringViewItem = this.context.createViewItem(this.id, enteringRoute, routeInfo); + this.context.addViewItem(enteringViewItem); + } + + // Handle transition based on ion-page element availability + if (enteringViewItem && enteringViewItem.ionPageElement) { + // Clear waiting state + if (this.waitingForIonPage) { + this.waitingForIonPage = false; + } + if (this.ionPageWaitTimeout) { + clearTimeout(this.ionPageWaitTimeout); + this.ionPageWaitTimeout = undefined; } - this.forceUpdate(); + this.handleReadyEnteringView(routeInfo, enteringViewItem, leavingViewItem, shouldUnmountLeavingViewItem); + } else if (enteringViewItem && !enteringViewItem.ionPageElement) { + // Wait for ion-page to mount + this.handleWaitingForIonPage(routeInfo, enteringViewItem, leavingViewItem, shouldUnmountLeavingViewItem); + return; + } else if (!enteringViewItem && !enteringRoute) { + // No view or route found - likely leaving to another outlet + if (leavingViewItem) { + hideIonPageElement(leavingViewItem.ionPageElement); + if (shouldUnmountLeavingViewItem) { + leavingViewItem.mount = false; + } + } } + + this.forceUpdate(); } + /** + * Registers an `` DOM element with the `StackManager`. + * This is called when `` has been mounted. + * + * @param page The element of the rendered ``. + * @param routeInfo The route information that associates with ``. + */ registerIonPage(page: HTMLElement, routeInfo: RouteInfo) { + this.waitingForIonPage = false; + if (this.ionPageWaitTimeout) { + clearTimeout(this.ionPageWaitTimeout); + this.ionPageWaitTimeout = undefined; + } + this.pendingPageTransition = false; const foundView = this.context.findViewItemByRouteInfo(routeInfo, this.id); if (foundView) { const oldPageElement = foundView.ionPageElement; @@ -209,97 +663,66 @@ export class StackManager extends React.PureComponent`. + */ async setupRouterOutlet(routerOutlet: HTMLIonRouterOutletElement) { const canStart = () => { const config = getConfig(); + // Check if swipe back is enabled in config (default to true for iOS mode) const swipeEnabled = config && config.get('swipeBackEnabled', routerOutlet.mode === 'ios'); if (!swipeEnabled) { return false; } const { routeInfo } = this.props; + const swipeBackRouteInfo = this.getSwipeBackRouteInfo(); + const enteringViewItem = this.context.findViewItemByRouteInfo(swipeBackRouteInfo, this.id, false); - const propsToUse = - this.prevProps && this.prevProps.routeInfo.pathname === routeInfo.pushedByRoute - ? this.prevProps.routeInfo - : ({ pathname: routeInfo.pushedByRoute || '' } as any); - const enteringViewItem = this.context.findViewItemByRouteInfo(propsToUse, this.id, false); - - return ( + const canStartSwipe = !!enteringViewItem && - /** - * The root url '/' is treated as - * the first view item (but is never mounted), - * so we do not want to swipe back to the - * root url. - */ + // The root url '/' is treated as the first view item (but is never mounted), + // so we do not want to swipe back to the root url. enteringViewItem.mount && - /** - * When on the first page (whatever view - * you land on after the root url) it - * is possible for findViewItemByRouteInfo to - * return the exact same view you are currently on. - * Make sure that we are not swiping back to the same - * instances of a view. - */ - enteringViewItem.routeData.match.path !== routeInfo.pathname - ); + // When on the first page it is possible for findViewItemByRouteInfo to + // return the exact same view you are currently on. + // Make sure that we are not swiping back to the same instances of a view. + enteringViewItem.routeData.match.pattern.path !== routeInfo.pathname; + + return canStartSwipe; }; const onStart = async () => { const { routeInfo } = this.props; - - const propsToUse = - this.prevProps && this.prevProps.routeInfo.pathname === routeInfo.pushedByRoute - ? this.prevProps.routeInfo - : ({ pathname: routeInfo.pushedByRoute || '' } as any); - const enteringViewItem = this.context.findViewItemByRouteInfo(propsToUse, this.id, false); + const swipeBackRouteInfo = this.getSwipeBackRouteInfo(); + const enteringViewItem = this.context.findViewItemByRouteInfo(swipeBackRouteInfo, this.id, false); const leavingViewItem = this.context.findViewItemByRouteInfo(routeInfo, this.id, false); - /** - * When the gesture starts, kick off - * a transition that is controlled - * via a swipe gesture. - */ + // When the gesture starts, kick off a transition controlled via swipe gesture if (enteringViewItem && leavingViewItem) { await this.transitionPage(routeInfo, enteringViewItem, leavingViewItem, 'back', true); } return Promise.resolve(); }; + const onEnd = (shouldContinue: boolean) => { if (shouldContinue) { + // User finished the swipe gesture, so complete the back navigation this.skipTransition = true; - this.context.goBack(); } else { - /** - * In the event that the swipe - * gesture was aborted, we should - * re-hide the page that was going to enter. - */ + // Swipe gesture was aborted - re-hide the page that was going to enter const { routeInfo } = this.props; - - const propsToUse = - this.prevProps && this.prevProps.routeInfo.pathname === routeInfo.pushedByRoute - ? this.prevProps.routeInfo - : ({ pathname: routeInfo.pushedByRoute || '' } as any); - const enteringViewItem = this.context.findViewItemByRouteInfo(propsToUse, this.id, false); + const swipeBackRouteInfo = this.getSwipeBackRouteInfo(); + const enteringViewItem = this.context.findViewItemByRouteInfo(swipeBackRouteInfo, this.id, false); const leavingViewItem = this.context.findViewItemByRouteInfo(routeInfo, this.id, false); - /** - * Ionic React has a design defect where it - * a) Unmounts the leaving view item when using parameterized routes - * b) Considers the current view to be the entering view when using - * parameterized routes - * - * As a result, we should not hide the view item here - * as it will cause the current view to be hidden. - */ + // Don't hide if entering and leaving are the same (parameterized route edge case) if (enteringViewItem !== leavingViewItem && enteringViewItem?.ionPageElement !== undefined) { - const { ionPageElement } = enteringViewItem; - ionPageElement.setAttribute('aria-hidden', 'true'); - ionPageElement.classList.add('ion-page-hidden'); + hideIonPageElement(enteringViewItem.ionPageElement); } } }; @@ -311,6 +734,18 @@ export class StackManager extends React.PureComponent { + // Callback triggers re-render when view items are modified during getChildrenToRender this.forceUpdate(); }); @@ -405,13 +851,16 @@ export class StackManager extends React.PureComponent { if (ionRouterOutlet.props.setRef) { + // Needed to handle external refs from devs. ionRouterOutlet.props.setRef(node); } if (ionRouterOutlet.props.forwardedRef) { + // Needed to handle external refs from devs. ionRouterOutlet.props.forwardedRef.current = node; } this.routerOutletElement = node; const { ref } = ionRouterOutlet as any; + // Check for legacy refs. if (typeof ref === 'function') { ref(node); } @@ -430,38 +879,139 @@ export class StackManager extends React.PureComponent` node matching the current route info. + * If no `` can be matched, a fallback node is returned. + * Routes are prioritized by specificity (most specific first). + * + * @param node The root node to search for `` nodes. + * @param routeInfo The route information to match against. + * @param parentPath The parent path that was matched by the parent outlet (for nested routing) + */ +function findRouteByRouteInfo(node: React.ReactNode, routeInfo: RouteInfo, parentPath?: string) { let matchedNode: React.ReactNode; - React.Children.forEach(node as React.ReactElement, (child: React.ReactElement) => { + let fallbackNode: React.ReactNode; + + // `` nodes are rendered inside of a node + const routesChildren = getRoutesChildren(node) ?? node; + + // Collect all route children + const routeChildren = React.Children.toArray(routesChildren).filter( + (child): child is React.ReactElement => React.isValidElement(child) && child.type === Route + ); + + // Sort routes by specificity (most specific first) + const sortedRoutes = routeChildren.sort((a, b) => { + const pathA = a.props.path || ''; + const pathB = b.props.path || ''; + + // Index routes come first + if (a.props.index && !b.props.index) return -1; + if (!a.props.index && b.props.index) return 1; + + // Wildcard-only routes (*) should come LAST + const aIsWildcardOnly = pathA === '*'; + const bIsWildcardOnly = pathB === '*'; + + if (!aIsWildcardOnly && bIsWildcardOnly) return -1; + if (aIsWildcardOnly && !bIsWildcardOnly) return 1; + + // Exact matches (no wildcards/params) come before wildcard/param routes + const aHasWildcard = pathA.includes('*') || pathA.includes(':'); + const bHasWildcard = pathB.includes('*') || pathB.includes(':'); + + if (!aHasWildcard && bHasWildcard) return -1; + if (aHasWildcard && !bHasWildcard) return 1; + + // Among routes with same wildcard status, longer paths are more specific + if (pathA.length !== pathB.length) { + return pathB.length - pathA.length; + } + + return 0; + }); + + // For nested routes in React Router 6, we need to extract the relative path + // that this outlet should be responsible for matching + let pathnameToMatch = routeInfo.pathname; + + // Check if we have relative routes (routes that don't start with '/') + const hasRelativeRoutes = sortedRoutes.some((r) => r.props.path && !r.props.path.startsWith('/')); + const hasIndexRoute = sortedRoutes.some((r) => r.props.index); + + // SIMPLIFIED: Trust React Router 6's matching more, compute relative path when parent is known + if ((hasRelativeRoutes || hasIndexRoute) && parentPath) { + const parentPrefix = parentPath.replace('/*', ''); + const normalizedParent = stripTrailingSlash(parentPrefix); + const normalizedPathname = stripTrailingSlash(routeInfo.pathname); + + // Only compute relative path if pathname is within parent scope + if (normalizedPathname.startsWith(normalizedParent + '/') || normalizedPathname === normalizedParent) { + const pathSegments = routeInfo.pathname.split('/').filter(Boolean); + const parentSegments = normalizedParent.split('/').filter(Boolean); + const relativeSegments = pathSegments.slice(parentSegments.length); + pathnameToMatch = relativeSegments.join('/'); // Empty string is valid for index routes + } + } + + // Find the first matching route + for (const child of sortedRoutes) { const match = matchPath({ - pathname: routeInfo.pathname, + pathname: pathnameToMatch, componentProps: child.props, }); + if (match) { matchedNode = child; + break; } - }); + } if (matchedNode) { return matchedNode; } - // If we haven't found a node - // try to find one that doesn't have a path or from prop, that will be our not found route - React.Children.forEach(node as React.ReactElement, (child: React.ReactElement) => { - if (!(child.props.path || child.props.from)) { - matchedNode = child; + + // If we haven't found a node, try to find one that doesn't have a path prop (fallback route) + // BUT only return the fallback if the current pathname is within the outlet's scope. + // For outlets with absolute paths, compute the common prefix to determine scope. + const absolutePathRoutes = routeChildren.filter((r) => r.props.path && r.props.path.startsWith('/')); + + // Determine if pathname is within scope before returning fallback + let isPathnameInScope = true; + + if (absolutePathRoutes.length > 0) { + // Find common prefix of all absolute paths to determine outlet scope + const absolutePaths = absolutePathRoutes.map((r) => r.props.path as string); + const commonPrefix = computeCommonPrefix(absolutePaths); + + // If we have a common prefix, check if the current pathname is within that scope + if (commonPrefix && commonPrefix !== '/') { + isPathnameInScope = routeInfo.pathname.startsWith(commonPrefix); } - }); + } + + // Only look for fallback route if pathname is within scope + if (isPathnameInScope) { + for (const child of routeChildren) { + if (!child.props.path) { + fallbackNode = child; + break; + } + } + } - return matchedNode; + return matchedNode ?? fallbackNode; } function matchComponent(node: React.ReactElement, pathname: string, forceExact?: boolean) { + const routePath: string | undefined = node?.props?.path; + const pathnameToMatch = derivePathnameToMatch(pathname, routePath); + return matchPath({ - pathname, + pathname: pathnameToMatch, componentProps: { ...node.props, - exact: forceExact, + end: forceExact, }, }); } diff --git a/packages/react-router/src/ReactRouter/utils/computeParentPath.ts b/packages/react-router/src/ReactRouter/utils/computeParentPath.ts new file mode 100644 index 00000000000..3f47672a445 --- /dev/null +++ b/packages/react-router/src/ReactRouter/utils/computeParentPath.ts @@ -0,0 +1,259 @@ +import type React from 'react'; + +import { matchPath } from './pathMatching'; + +/** + * Finds the longest common prefix among an array of paths. + * Used to determine the scope of an outlet with absolute routes. + * + * @param paths An array of absolute path strings. + * @returns The common prefix shared by all paths. + */ +export const computeCommonPrefix = (paths: string[]): string => { + if (paths.length === 0) return ''; + if (paths.length === 1) { + // For a single path, extract the directory-like prefix + // e.g., /dynamic-routes/home -> /dynamic-routes + const segments = paths[0].split('/').filter(Boolean); + if (segments.length > 1) { + return '/' + segments.slice(0, -1).join('/'); + } + return '/' + segments[0]; + } + + // Split all paths into segments + const segmentArrays = paths.map((p) => p.split('/').filter(Boolean)); + const minLength = Math.min(...segmentArrays.map((s) => s.length)); + + const commonSegments: string[] = []; + for (let i = 0; i < minLength; i++) { + const segment = segmentArrays[0][i]; + // Skip segments with route parameters or wildcards + if (segment.includes(':') || segment.includes('*')) { + break; + } + const allMatch = segmentArrays.every((s) => s[i] === segment); + if (allMatch) { + commonSegments.push(segment); + } else { + break; + } + } + + return commonSegments.length > 0 ? '/' + commonSegments.join('/') : ''; +}; + +/** + * Checks if a route is a specific match (not wildcard or index). + * + * @param route The route element to check. + * @param remainingPath The remaining path to match against. + * @returns True if the route specifically matches the remaining path. + */ +export const isSpecificRouteMatch = (route: React.ReactElement, remainingPath: string): boolean => { + const routePath = route.props.path; + const isWildcardOnly = routePath === '*' || routePath === '/*'; + const isIndex = route.props.index; + + // Skip wildcards and index routes + if (isIndex || isWildcardOnly) { + return false; + } + + return !!matchPath({ + pathname: remainingPath, + componentProps: route.props, + }); +}; + +/** + * Result of parent path computation. + */ +export interface ParentPathResult { + parentPath: string | undefined; + outletMountPath: string | undefined; +} + +interface RouteAnalysis { + hasRelativeRoutes: boolean; + hasIndexRoute: boolean; + hasWildcardRoute: boolean; + routeChildren: React.ReactElement[]; +} + +/** + * Analyzes route children to determine their characteristics. + * + * @param routeChildren The route children to analyze. + * @returns Analysis of the route characteristics. + */ +export const analyzeRouteChildren = (routeChildren: React.ReactElement[]): RouteAnalysis => { + const hasRelativeRoutes = routeChildren.some((route) => { + const path = route.props.path; + return path && !path.startsWith('/') && path !== '*'; + }); + + const hasIndexRoute = routeChildren.some((route) => route.props.index); + + const hasWildcardRoute = routeChildren.some((route) => { + const routePath = route.props.path; + return routePath === '*' || routePath === '/*'; + }); + + return { hasRelativeRoutes, hasIndexRoute, hasWildcardRoute, routeChildren }; +}; + +interface ComputeParentPathOptions { + currentPathname: string; + outletMountPath: string | undefined; + routeChildren: React.ReactElement[]; + hasRelativeRoutes: boolean; + hasIndexRoute: boolean; + hasWildcardRoute: boolean; +} + +/** + * Computes the parent path for a nested outlet based on the current pathname + * and the outlet's route configuration. + * + * The algorithm finds the shortest parent path where a route matches the remaining path. + * Priority: specific routes > wildcard routes > index routes (only at mount point) + * + * @param options The options for computing the parent path. + * @returns The computed parent path result. + */ +export const computeParentPath = (options: ComputeParentPathOptions): ParentPathResult => { + const { currentPathname, outletMountPath, routeChildren, hasRelativeRoutes, hasIndexRoute, hasWildcardRoute } = + options; + + // If this outlet previously established a mount path and the current + // pathname is outside of that scope, do not attempt to re-compute a new + // parent path. + if (outletMountPath && !currentPathname.startsWith(outletMountPath)) { + return { parentPath: undefined, outletMountPath }; + } + + if ((hasRelativeRoutes || hasIndexRoute) && currentPathname.includes('/')) { + const segments = currentPathname.split('/').filter(Boolean); + + if (segments.length >= 1) { + // Find matches at each level, keeping track of the FIRST (shortest) match + let firstSpecificMatch: string | undefined = undefined; + let firstWildcardMatch: string | undefined = undefined; + let indexMatchAtMount: string | undefined = undefined; + + for (let i = 1; i <= segments.length; i++) { + const parentPath = '/' + segments.slice(0, i).join('/'); + const remainingPath = segments.slice(i).join('/'); + + // Check for specific (non-wildcard, non-index) route matches + const hasSpecificMatch = routeChildren.some((route) => isSpecificRouteMatch(route, remainingPath)); + if (hasSpecificMatch && !firstSpecificMatch) { + firstSpecificMatch = parentPath; + // Found a specific match - this is our answer for non-index routes + break; + } + + // Check if wildcard would match this remaining path + // Only if remaining is non-empty (wildcard needs something to match) + if (remainingPath !== '' && remainingPath !== '/' && hasWildcardRoute && !firstWildcardMatch) { + // Check if any specific route could plausibly match this remaining path + const remainingFirstSegment = remainingPath.split('/')[0]; + const couldAnyRouteMatch = routeChildren.some((route) => { + const routePath = route.props.path as string | undefined; + if (!routePath || routePath === '*' || routePath === '/*') return false; + if (route.props.index) return false; + + const routeFirstSegment = routePath.split('/')[0].replace(/[*:]/g, ''); + if (!routeFirstSegment) return false; + + // Check for prefix overlap (either direction) + return ( + routeFirstSegment.startsWith(remainingFirstSegment.slice(0, 3)) || + remainingFirstSegment.startsWith(routeFirstSegment.slice(0, 3)) + ); + }); + + // Only save wildcard match if no specific route could match + if (!couldAnyRouteMatch) { + firstWildcardMatch = parentPath; + // Continue looking - might find a specific match at a longer path + } + } + + // Check for index route match when remaining path is empty + // BUT only at the outlet's mount path level + if ((remainingPath === '' || remainingPath === '/') && hasIndexRoute) { + // Index route matches when current path exactly matches the mount path + // If we already have an outletMountPath, index should only match there + if (outletMountPath) { + if (parentPath === outletMountPath) { + indexMatchAtMount = parentPath; + } + } else { + // No mount path set yet - index would establish this as mount path + // But only if we haven't found a better match + indexMatchAtMount = parentPath; + } + } + } + + // Determine the best parent path: + // 1. Specific match (routes like tabs/*, favorites) - highest priority + // 2. Wildcard match (route path="*") - catches unmatched segments + // 3. Index match - only valid at the outlet's mount point, not deeper + let bestPath: string | undefined = undefined; + + if (firstSpecificMatch) { + bestPath = firstSpecificMatch; + } else if (firstWildcardMatch) { + bestPath = firstWildcardMatch; + } else if (indexMatchAtMount) { + // Only use index match if no specific or wildcard matched + // This handles the case where pathname exactly matches the mount path + bestPath = indexMatchAtMount; + } + + // Store the mount path when we first successfully match a route + let newOutletMountPath = outletMountPath; + if (!outletMountPath && bestPath) { + newOutletMountPath = bestPath; + } + + // If we have a mount path, verify the current pathname is within scope + if (newOutletMountPath && !currentPathname.startsWith(newOutletMountPath)) { + return { parentPath: undefined, outletMountPath: newOutletMountPath }; + } + + return { parentPath: bestPath, outletMountPath: newOutletMountPath }; + } + } + + // Handle outlets with ONLY absolute routes (no relative routes or index routes) + // Compute the common prefix of all absolute routes to determine the outlet's scope + if (!hasRelativeRoutes && !hasIndexRoute) { + const absolutePathRoutes = routeChildren.filter((route) => { + const path = route.props.path; + return path && path.startsWith('/'); + }); + + if (absolutePathRoutes.length > 0) { + const absolutePaths = absolutePathRoutes.map((r) => r.props.path as string); + const commonPrefix = computeCommonPrefix(absolutePaths); + + if (commonPrefix && commonPrefix !== '/') { + // Set the mount path based on common prefix of absolute routes + const newOutletMountPath = outletMountPath || commonPrefix; + + // Check if current pathname is within scope + if (!currentPathname.startsWith(commonPrefix)) { + return { parentPath: undefined, outletMountPath: newOutletMountPath }; + } + + return { parentPath: commonPrefix, outletMountPath: newOutletMountPath }; + } + } + } + + return { parentPath: outletMountPath, outletMountPath }; +}; diff --git a/packages/react-router/src/ReactRouter/utils/matchPath.ts b/packages/react-router/src/ReactRouter/utils/matchPath.ts deleted file mode 100644 index 891eda08bb2..00000000000 --- a/packages/react-router/src/ReactRouter/utils/matchPath.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { matchPath as reactRouterMatchPath } from 'react-router'; - -interface MatchPathOptions { - /** - * The pathname to match against. - */ - pathname: string; - /** - * The props to match against, they are identical to the matching props `Route` accepts. - */ - componentProps: { - path?: string; - from?: string; - component?: any; - exact?: boolean; - }; -} - -/** - * @see https://v5.reactrouter.com/web/api/matchPath - */ -export const matchPath = ({ - pathname, - componentProps, -}: MatchPathOptions): false | ReturnType => { - const { exact, component } = componentProps; - - const path = componentProps.path || componentProps.from; - /*** - * The props to match against, they are identical - * to the matching props `Route` accepts. It could also be a string - * or an array of strings as shortcut for `{ path }`. - */ - const matchProps = { - exact, - path, - component, - }; - - const match = reactRouterMatchPath(pathname, matchProps); - - if (!match) { - return false; - } - - return match; -}; diff --git a/packages/react-router/src/ReactRouter/utils/pathMatching.ts b/packages/react-router/src/ReactRouter/utils/pathMatching.ts new file mode 100644 index 00000000000..a0ab74164f7 --- /dev/null +++ b/packages/react-router/src/ReactRouter/utils/pathMatching.ts @@ -0,0 +1,162 @@ +import type { PathMatch } from 'react-router'; +import { matchPath as reactRouterMatchPath } from 'react-router-dom'; + +/** + * Options for the matchPath function. + */ +interface MatchPathOptions { + /** + * The pathname to match against. + */ + pathname: string; + /** + * The props to match against, they are identical to the matching props `Route` accepts. + */ + componentProps: { + path?: string; + caseSensitive?: boolean; + end?: boolean; + index?: boolean; + }; +} + +/** + * The matchPath function is used only for matching paths, not rendering components or elements. + * @see https://reactrouter.com/v6/utils/match-path + */ +export const matchPath = ({ pathname, componentProps }: MatchPathOptions): PathMatch | null => { + const { path, index, ...restProps } = componentProps; + + // Handle index routes + if (index && !path) { + // Index routes match when there's no additional path after the parent route + // For example, in a nested outlet at /routing/*, the index route matches + // when the relative path is empty (i.e., we're exactly at /routing) + + // If pathname is empty or just "/", it should match the index route + if (pathname === '' || pathname === '/') { + return { + params: {}, + pathname: pathname, + pathnameBase: pathname || '/', + pattern: { + path: '', + caseSensitive: false, + end: true, + }, + }; + } + + // Otherwise, index routes don't match when there's additional path + return null; + } + + if (!path) { + return null; + } + + // For relative paths in nested routes (those that don't start with '/'), + // use React Router's matcher against a normalized path. + if (!path.startsWith('/')) { + const matchOptions: Parameters[0] = { + path: `/${path}`, + ...restProps, + }; + + if (matchOptions?.end === undefined) { + matchOptions.end = !path.endsWith('*'); + } + + const normalizedPathname = pathname.startsWith('/') ? pathname : `/${pathname}`; + const match = reactRouterMatchPath(matchOptions, normalizedPathname); + + if (match) { + // Adjust the match to remove the leading '/' we added + return { + ...match, + pathname: pathname, + pathnameBase: match.pathnameBase === '/' ? '' : match.pathnameBase.slice(1), + pattern: { + ...match.pattern, + path: path, + }, + }; + } + + // No match found + return null; + } + + // For absolute paths, use React Router's matcher directly. + // React Router v6 routes default to `end: true` unless the pattern + // explicitly opts into wildcards with `*`. Mirror that behaviour so + // matching parity stays aligned with . + const matchOptions: Parameters[0] = { + path, + ...restProps, + }; + + if (matchOptions?.end === undefined) { + matchOptions.end = !path.endsWith('*'); + } + + return reactRouterMatchPath(matchOptions, pathname); +}; + +/** + * Determines the portion of a pathname that a given route pattern should match against. + * For absolute route patterns we return the full pathname. For relative patterns we + * strip off the already-matched parent segments so React Router receives the remainder. + */ +export const derivePathnameToMatch = (fullPathname: string, routePath?: string): string => { + if (!routePath || routePath === '' || routePath.startsWith('/')) { + return fullPathname; + } + + const trimmedPath = fullPathname.startsWith('/') ? fullPathname.slice(1) : fullPathname; + if (!trimmedPath) { + return ''; + } + + const fullSegments = trimmedPath.split('/').filter(Boolean); + if (fullSegments.length === 0) { + return ''; + } + + const routeSegments = routePath.split('/').filter(Boolean); + if (routeSegments.length === 0) { + return trimmedPath; + } + + const wildcardIndex = routeSegments.findIndex((segment) => segment === '*' || segment === '**'); + + if (wildcardIndex >= 0) { + const baseSegments = routeSegments.slice(0, wildcardIndex); + if (baseSegments.length === 0) { + return trimmedPath; + } + + const startIndex = fullSegments.findIndex((_, idx) => + baseSegments.every((seg, segIdx) => { + const target = fullSegments[idx + segIdx]; + if (!target) { + return false; + } + if (seg.startsWith(':')) { + return true; + } + return target === seg; + }) + ); + + if (startIndex >= 0) { + return fullSegments.slice(startIndex).join('/'); + } + } + + if (routeSegments.length <= fullSegments.length) { + return fullSegments.slice(fullSegments.length - routeSegments.length).join('/'); + } + + return fullSegments[fullSegments.length - 1] ?? trimmedPath; +}; diff --git a/packages/react-router/src/ReactRouter/utils/pathNormalization.ts b/packages/react-router/src/ReactRouter/utils/pathNormalization.ts new file mode 100644 index 00000000000..0ce180e4a18 --- /dev/null +++ b/packages/react-router/src/ReactRouter/utils/pathNormalization.ts @@ -0,0 +1,37 @@ +/** + * Ensures the given path has a leading slash. + * + * @param value The path string to normalize. + * @returns The path with a leading slash. + */ +export const ensureLeadingSlash = (value: string): string => { + if (value === '') { + return '/'; + } + return value.startsWith('/') ? value : `/${value}`; +}; + +/** + * Strips the trailing slash from a path, unless it's the root path. + * + * @param value The path string to normalize. + * @returns The path without a trailing slash. + */ +export const stripTrailingSlash = (value: string): string => { + return value.length > 1 && value.endsWith('/') ? value.slice(0, -1) : value; +}; + +/** + * Normalizes a pathname for comparison by ensuring a leading slash + * and removing trailing slashes. + * + * @param value The pathname to normalize, can be undefined. + * @returns A normalized pathname string. + */ +export const normalizePathnameForComparison = (value: string | undefined): string => { + if (!value || value === '') { + return '/'; + } + const withLeadingSlash = ensureLeadingSlash(value); + return stripTrailingSlash(withLeadingSlash); +}; diff --git a/packages/react-router/src/ReactRouter/utils/routeElements.ts b/packages/react-router/src/ReactRouter/utils/routeElements.ts new file mode 100644 index 00000000000..e0e52dd620f --- /dev/null +++ b/packages/react-router/src/ReactRouter/utils/routeElements.ts @@ -0,0 +1,51 @@ +import React from 'react'; +import { Navigate, Route, Routes } from 'react-router-dom'; + +/** + * Extracts the children from a Routes wrapper component. + * The use of `` is encouraged with React Router v6. + * + * @param node The React node to extract Routes children from. + * @returns The children of the Routes component, or undefined if not found. + */ +export const getRoutesChildren = (node: React.ReactNode): React.ReactNode | undefined => { + let routesNode: React.ReactNode; + React.Children.forEach(node as React.ReactElement, (child: React.ReactElement) => { + if (child.type === Routes) { + routesNode = child; + } + }); + + if (routesNode) { + // The children of the `` component are most likely + // (and should be) the `` components. + return (routesNode as React.ReactElement).props.children; + } + return undefined; +}; + +/** + * Extracts Route children from a node (either directly or from a Routes wrapper). + * + * @param children The children to extract routes from. + * @returns An array of Route elements. + */ +export const extractRouteChildren = (children: React.ReactNode): React.ReactElement[] => { + const routesChildren = getRoutesChildren(children) ?? children; + return React.Children.toArray(routesChildren).filter( + (child): child is React.ReactElement => React.isValidElement(child) && child.type === Route + ); +}; + +/** + * Checks if a React element is a Navigate component (redirect). + * + * @param element The element to check. + * @returns True if the element is a Navigate component. + */ +export const isNavigateElement = (element: unknown): boolean => { + return ( + React.isValidElement(element) && + (element.type === Navigate || (typeof element.type === 'function' && element.type.name === 'Navigate')) + ); +}; diff --git a/packages/react-router/src/ReactRouter/utils/viewItemUtils.ts b/packages/react-router/src/ReactRouter/utils/viewItemUtils.ts new file mode 100644 index 00000000000..c5d8b84d197 --- /dev/null +++ b/packages/react-router/src/ReactRouter/utils/viewItemUtils.ts @@ -0,0 +1,26 @@ +import type { ViewItem } from '@ionic/react'; + +/** + * Sorts view items by route specificity (most specific first). + * - Exact matches (no wildcards/params) come first + * - Among wildcard routes, longer paths are more specific + * + * @param views The view items to sort. + * @returns A new sorted array of view items. + */ +export const sortViewsBySpecificity = (views: ViewItem[]): ViewItem[] => { + return [...views].sort((a, b) => { + const pathA = a.routeData?.childProps?.path || ''; + const pathB = b.routeData?.childProps?.path || ''; + + // Exact matches (no wildcards/params) come first + const aHasWildcard = pathA.includes('*') || pathA.includes(':'); + const bHasWildcard = pathB.includes('*') || pathB.includes(':'); + + if (!aHasWildcard && bHasWildcard) return -1; + if (aHasWildcard && !bHasWildcard) return 1; + + // Among wildcard routes, longer paths are more specific + return pathB.length - pathA.length; + }); +}; diff --git a/packages/react-router/test/apps/reactrouter5/package-lock.json b/packages/react-router/test/apps/reactrouter6/package-lock.json similarity index 99% rename from packages/react-router/test/apps/reactrouter5/package-lock.json rename to packages/react-router/test/apps/reactrouter6/package-lock.json index 8783c314b8f..418033c77b3 100644 --- a/packages/react-router/test/apps/reactrouter5/package-lock.json +++ b/packages/react-router/test/apps/reactrouter6/package-lock.json @@ -8,8 +8,8 @@ "name": "react-router-new", "version": "0.0.1", "dependencies": { - "@ionic/react": "^6.6.1", - "@ionic/react-router": "^6.6.1", + "@ionic/react": "^8.6.1", + "@ionic/react-router": "^8.6.1", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.4.3", @@ -17,11 +17,11 @@ "@types/react-dom": "^18.0.11", "@types/react-router": "^5.1.20", "@types/react-router-dom": "^5.3.3", - "ionicons": "^8.0.13", + "ionicons": "^6.0.4", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-router": "^5.3.4", - "react-router-dom": "^5.3.4", + "react-router": "^6.0.0", + "react-router-dom": "^6.0.0", "react-scripts": "^5.0.1", "sass-loader": "8.0.2", "typescript": "^4.4.2", @@ -2295,31 +2295,52 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, "node_modules/@ionic/core": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.6.1.tgz", - "integrity": "sha512-+LMBk7kUX55rvYQ35AiAXPNzbNm3zNx9ginvuCzByguMjl+N63lpdPzIEfeRURkmq7NByD1VqpodMj5c6Oq2KQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.6.2.tgz", + "integrity": "sha512-CGZ9CDp/XHtm9WrK3wt0ZtR2f2B76qEvJIaF/juCqmpza9Al6u2L9R/NTEwInDRCWfbkAIF22nHNH54/VvN78Q==", "dependencies": { - "@stencil/core": "^2.18.0", - "ionicons": "^6.1.3", + "@stencil/core": "4.33.1", + "ionicons": "^7.2.2", "tslib": "^2.1.0" } }, + "node_modules/@ionic/core/node_modules/@stencil/core": { + "version": "4.33.1", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.33.1.tgz", + "integrity": "sha512-12k9xhAJBkpg598it+NRmaYIdEe6TSnsL/v6/KRXDcUyTK11VYwZQej2eHnMWtqot+znJ+GNTqb5YbiXi+5Low==", + "bin": { + "stencil": "bin/stencil" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.10.0" + }, + "optionalDependencies": { + "@rollup/rollup-darwin-arm64": "4.34.9", + "@rollup/rollup-darwin-x64": "4.34.9", + "@rollup/rollup-linux-arm64-gnu": "4.34.9", + "@rollup/rollup-linux-arm64-musl": "4.34.9", + "@rollup/rollup-linux-x64-gnu": "4.34.9", + "@rollup/rollup-linux-x64-musl": "4.34.9", + "@rollup/rollup-win32-arm64-msvc": "4.34.9", + "@rollup/rollup-win32-x64-msvc": "4.34.9" + } + }, "node_modules/@ionic/core/node_modules/ionicons": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz", - "integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==", - "license": "MIT", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.4.0.tgz", + "integrity": "sha512-ZK94MMqgzMCPPMhmk8Ouu6goyVHFIlw/ACP6oe3FrikcI0N7CX0xcwVaEbUc0G/v3W0shI93vo+9ve/KpvcNhQ==", "dependencies": { - "@stencil/core": "^2.18.0" + "@stencil/core": "^4.0.3" } }, "node_modules/@ionic/react": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-6.6.1.tgz", - "integrity": "sha512-gq8FzC0CAPt6MpOFethe9+zIU7jg1JyWPWRANJ/UudlF05f2eFOzLgqe/EH0uIIsuDjeoM50hrqfuvg6x2j3UQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.6.2.tgz", + "integrity": "sha512-SXE1RnzGqj0MGKGs6D4UCk4rOghbLYI5qwANdZJuBxlIcrcBJuAySjneuTGt+Y3UHS8W3YZHFujRv2Gvb+zvqQ==", "dependencies": { - "@ionic/core": "6.6.1", - "ionicons": "^6.1.3", + "@ionic/core": "8.6.2", + "ionicons": "^7.0.0", "tslib": "*" }, "peerDependencies": { @@ -2328,11 +2349,11 @@ } }, "node_modules/@ionic/react-router": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-6.6.1.tgz", - "integrity": "sha512-9bHlz3MdzvkUyZ9QfxzcAGDtbRhZ7R5uMjm3UHvGhYS1Rdx4KIc8E5q31IQf7H6j2ULU9YcB7UeyW5ORxBX18Q==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-8.6.2.tgz", + "integrity": "sha512-wNVYZHEHkRkNimiK24bJ8KsWjuQyug7C+J/rNER7BKtZDzU3kWKVjvzD3P7kaiOf/DtVo+OrZNvYQJOuoIEhWg==", "dependencies": { - "@ionic/react": "6.6.1", + "@ionic/react": "8.6.2", "tslib": "*" }, "peerDependencies": { @@ -2342,13 +2363,34 @@ "react-router-dom": "^5.0.1" } }, + "node_modules/@ionic/react/node_modules/@stencil/core": { + "version": "4.35.1", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.35.1.tgz", + "integrity": "sha512-u65m3TbzOtpn679gUV4Yvi8YpInhRJ62js30a7YtXief9Ej/vzrhwDE22U0w4DMWJOYwAsJl133BUaZkWwnmzg==", + "bin": { + "stencil": "bin/stencil" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.10.0" + }, + "optionalDependencies": { + "@rollup/rollup-darwin-arm64": "4.34.9", + "@rollup/rollup-darwin-x64": "4.34.9", + "@rollup/rollup-linux-arm64-gnu": "4.34.9", + "@rollup/rollup-linux-arm64-musl": "4.34.9", + "@rollup/rollup-linux-x64-gnu": "4.34.9", + "@rollup/rollup-linux-x64-musl": "4.34.9", + "@rollup/rollup-win32-arm64-msvc": "4.34.9", + "@rollup/rollup-win32-x64-msvc": "4.34.9" + } + }, "node_modules/@ionic/react/node_modules/ionicons": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz", - "integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==", - "license": "MIT", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.4.0.tgz", + "integrity": "sha512-ZK94MMqgzMCPPMhmk8Ouu6goyVHFIlw/ACP6oe3FrikcI0N7CX0xcwVaEbUc0G/v3W0shI93vo+9ve/KpvcNhQ==", "dependencies": { - "@stencil/core": "^2.18.0" + "@stencil/core": "^4.0.3" } }, "node_modules/@istanbuljs/load-nyc-config": { @@ -3703,6 +3745,14 @@ "node": ">= 8" } }, + "node_modules/@remix-run/router": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz", + "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -3800,7 +3850,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -3813,7 +3862,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -3826,7 +3874,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -3839,7 +3886,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -3852,7 +3898,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -3865,7 +3910,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "linux" @@ -3878,7 +3922,6 @@ "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "win32" @@ -3891,7 +3934,6 @@ "cpu": [ "x64" ], - "license": "MIT", "optional": true, "os": [ "win32" @@ -10771,27 +10813,6 @@ "he": "bin/he" } }, - "node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -11216,35 +11237,11 @@ } }, "node_modules/ionicons": { - "version": "8.0.13", - "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-8.0.13.tgz", - "integrity": "sha512-2QQVyG2P4wszne79jemMjWYLp0DBbDhr4/yFroPCxvPP1wtMxgdIV3l5n+XZ5E9mgoXU79w7yTWpm2XzJsISxQ==", - "license": "MIT", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz", + "integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==", "dependencies": { - "@stencil/core": "^4.35.3" - } - }, - "node_modules/ionicons/node_modules/@stencil/core": { - "version": "4.35.3", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.35.3.tgz", - "integrity": "sha512-RH5/I+amV31QI8TMXhXkAkjzs2eod6Y07jkUYTl9kMB+X7c5wUpv95Y/2LtcAx0Rqdhh4SHbJiwpr0ApBZmv0g==", - "license": "MIT", - "bin": { - "stencil": "bin/stencil" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.10.0" - }, - "optionalDependencies": { - "@rollup/rollup-darwin-arm64": "4.34.9", - "@rollup/rollup-darwin-x64": "4.34.9", - "@rollup/rollup-linux-arm64-gnu": "4.34.9", - "@rollup/rollup-linux-arm64-musl": "4.34.9", - "@rollup/rollup-linux-x64-gnu": "4.34.9", - "@rollup/rollup-linux-x64-musl": "4.34.9", - "@rollup/rollup-win32-arm64-msvc": "4.34.9", - "@rollup/rollup-win32-x64-msvc": "4.34.9" + "@stencil/core": "^2.18.0" } }, "node_modules/ipaddr.js": { @@ -11695,11 +11692,6 @@ "node": ">=8" } }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -16428,14 +16420,6 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, - "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dependencies": { - "isarray": "0.0.1" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -18388,39 +18372,33 @@ } }, "node_modules/react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz", + "integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==", "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "@remix-run/router": "1.23.0" + }, + "engines": { + "node": ">=14.0.0" }, "peerDependencies": { - "react": ">=15" + "react": ">=16.8" } }, "node_modules/react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz", + "integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==", "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "@remix-run/router": "1.23.0", + "react-router": "6.30.1" + }, + "engines": { + "node": ">=14.0.0" }, "peerDependencies": { - "react": ">=15" + "react": ">=16.8", + "react-dom": ">=16.8" } }, "node_modules/react-scripts": { @@ -19372,11 +19350,6 @@ "node": ">=8" } }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, "node_modules/resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", @@ -20817,16 +20790,6 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, - "node_modules/tiny-invariant": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", - "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -21264,11 +21227,6 @@ "node": ">= 8" } }, - "node_modules/value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -24028,51 +23986,81 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, "@ionic/core": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.6.1.tgz", - "integrity": "sha512-+LMBk7kUX55rvYQ35AiAXPNzbNm3zNx9ginvuCzByguMjl+N63lpdPzIEfeRURkmq7NByD1VqpodMj5c6Oq2KQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.6.2.tgz", + "integrity": "sha512-CGZ9CDp/XHtm9WrK3wt0ZtR2f2B76qEvJIaF/juCqmpza9Al6u2L9R/NTEwInDRCWfbkAIF22nHNH54/VvN78Q==", "requires": { - "@stencil/core": "^2.18.0", - "ionicons": "^6.1.3", + "@stencil/core": "4.33.1", + "ionicons": "^7.2.2", "tslib": "^2.1.0" }, "dependencies": { + "@stencil/core": { + "version": "4.33.1", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.33.1.tgz", + "integrity": "sha512-12k9xhAJBkpg598it+NRmaYIdEe6TSnsL/v6/KRXDcUyTK11VYwZQej2eHnMWtqot+znJ+GNTqb5YbiXi+5Low==", + "requires": { + "@rollup/rollup-darwin-arm64": "4.34.9", + "@rollup/rollup-darwin-x64": "4.34.9", + "@rollup/rollup-linux-arm64-gnu": "4.34.9", + "@rollup/rollup-linux-arm64-musl": "4.34.9", + "@rollup/rollup-linux-x64-gnu": "4.34.9", + "@rollup/rollup-linux-x64-musl": "4.34.9", + "@rollup/rollup-win32-arm64-msvc": "4.34.9", + "@rollup/rollup-win32-x64-msvc": "4.34.9" + } + }, "ionicons": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz", - "integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.4.0.tgz", + "integrity": "sha512-ZK94MMqgzMCPPMhmk8Ouu6goyVHFIlw/ACP6oe3FrikcI0N7CX0xcwVaEbUc0G/v3W0shI93vo+9ve/KpvcNhQ==", "requires": { - "@stencil/core": "^2.18.0" + "@stencil/core": "^4.0.3" } } } }, "@ionic/react": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-6.6.1.tgz", - "integrity": "sha512-gq8FzC0CAPt6MpOFethe9+zIU7jg1JyWPWRANJ/UudlF05f2eFOzLgqe/EH0uIIsuDjeoM50hrqfuvg6x2j3UQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.6.2.tgz", + "integrity": "sha512-SXE1RnzGqj0MGKGs6D4UCk4rOghbLYI5qwANdZJuBxlIcrcBJuAySjneuTGt+Y3UHS8W3YZHFujRv2Gvb+zvqQ==", "requires": { - "@ionic/core": "6.6.1", - "ionicons": "^6.1.3", + "@ionic/core": "8.6.2", + "ionicons": "^7.0.0", "tslib": "*" }, "dependencies": { + "@stencil/core": { + "version": "4.35.1", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.35.1.tgz", + "integrity": "sha512-u65m3TbzOtpn679gUV4Yvi8YpInhRJ62js30a7YtXief9Ej/vzrhwDE22U0w4DMWJOYwAsJl133BUaZkWwnmzg==", + "requires": { + "@rollup/rollup-darwin-arm64": "4.34.9", + "@rollup/rollup-darwin-x64": "4.34.9", + "@rollup/rollup-linux-arm64-gnu": "4.34.9", + "@rollup/rollup-linux-arm64-musl": "4.34.9", + "@rollup/rollup-linux-x64-gnu": "4.34.9", + "@rollup/rollup-linux-x64-musl": "4.34.9", + "@rollup/rollup-win32-arm64-msvc": "4.34.9", + "@rollup/rollup-win32-x64-msvc": "4.34.9" + } + }, "ionicons": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz", - "integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.4.0.tgz", + "integrity": "sha512-ZK94MMqgzMCPPMhmk8Ouu6goyVHFIlw/ACP6oe3FrikcI0N7CX0xcwVaEbUc0G/v3W0shI93vo+9ve/KpvcNhQ==", "requires": { - "@stencil/core": "^2.18.0" + "@stencil/core": "^4.0.3" } } } }, "@ionic/react-router": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-6.6.1.tgz", - "integrity": "sha512-9bHlz3MdzvkUyZ9QfxzcAGDtbRhZ7R5uMjm3UHvGhYS1Rdx4KIc8E5q31IQf7H6j2ULU9YcB7UeyW5ORxBX18Q==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-8.6.2.tgz", + "integrity": "sha512-wNVYZHEHkRkNimiK24bJ8KsWjuQyug7C+J/rNER7BKtZDzU3kWKVjvzD3P7kaiOf/DtVo+OrZNvYQJOuoIEhWg==", "requires": { - "@ionic/react": "6.6.1", + "@ionic/react": "8.6.2", "tslib": "*" } }, @@ -25068,6 +25056,11 @@ } } }, + "@remix-run/router": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz", + "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==" + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -30255,27 +30248,6 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, - "history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "requires": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -30582,28 +30554,11 @@ "dev": true }, "ionicons": { - "version": "8.0.13", - "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-8.0.13.tgz", - "integrity": "sha512-2QQVyG2P4wszne79jemMjWYLp0DBbDhr4/yFroPCxvPP1wtMxgdIV3l5n+XZ5E9mgoXU79w7yTWpm2XzJsISxQ==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz", + "integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==", "requires": { - "@stencil/core": "^4.35.3" - }, - "dependencies": { - "@stencil/core": { - "version": "4.35.3", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.35.3.tgz", - "integrity": "sha512-RH5/I+amV31QI8TMXhXkAkjzs2eod6Y07jkUYTl9kMB+X7c5wUpv95Y/2LtcAx0Rqdhh4SHbJiwpr0ApBZmv0g==", - "requires": { - "@rollup/rollup-darwin-arm64": "4.34.9", - "@rollup/rollup-darwin-x64": "4.34.9", - "@rollup/rollup-linux-arm64-gnu": "4.34.9", - "@rollup/rollup-linux-arm64-musl": "4.34.9", - "@rollup/rollup-linux-x64-gnu": "4.34.9", - "@rollup/rollup-linux-x64-musl": "4.34.9", - "@rollup/rollup-win32-arm64-msvc": "4.34.9", - "@rollup/rollup-win32-x64-msvc": "4.34.9" - } - } + "@stencil/core": "^2.18.0" } }, "ipaddr.js": { @@ -30892,11 +30847,6 @@ "is-docker": "^2.0.0" } }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -34400,14 +34350,6 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "requires": { - "isarray": "0.0.1" - } - }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -35656,33 +35598,20 @@ "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==" }, "react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz", + "integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==", "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "@remix-run/router": "1.23.0" } }, "react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz", + "integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==", "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "@remix-run/router": "1.23.0", + "react-router": "6.30.1" } }, "react-scripts": { @@ -36303,11 +36232,6 @@ } } }, - "resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, "resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", @@ -37413,16 +37337,6 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, - "tiny-invariant": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", - "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -37759,11 +37673,6 @@ } } }, - "value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/packages/react-router/test/apps/reactrouter5/package.json b/packages/react-router/test/apps/reactrouter6/package.json similarity index 80% rename from packages/react-router/test/apps/reactrouter5/package.json rename to packages/react-router/test/apps/reactrouter6/package.json index 4e59232f653..5d2fe05ebf2 100644 --- a/packages/react-router/test/apps/reactrouter5/package.json +++ b/packages/react-router/test/apps/reactrouter6/package.json @@ -2,21 +2,25 @@ "name": "react-router-new", "version": "0.0.1", "private": true, + "overrides": { + "@ionic/react-router": { + "react-router": "$react-router", + "react-router-dom": "$react-router-dom" + } + }, "dependencies": { - "@ionic/react": "^6.6.1", - "@ionic/react-router": "^6.6.1", + "@ionic/react": "^8.6.1", + "@ionic/react-router": "^8.6.1", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.4.3", "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", - "@types/react-router": "^5.1.20", - "@types/react-router-dom": "^5.3.3", - "ionicons": "^8.0.13", + "ionicons": "^6.0.4", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-router": "^5.3.4", - "react-router-dom": "^5.3.4", + "react-router": "^6.0.0", + "react-router-dom": "^6.0.0", "react-scripts": "^5.0.1", "sass-loader": "8.0.2", "typescript": "^4.4.2", @@ -52,6 +56,7 @@ "devDependencies": { "concurrently": "^6.3.0", "cypress": "^13.2.0", + "cypress-terminal-report": "^5.3.0", "serve": "^14.0.1", "wait-on": "^6.0.0", "webpack-cli": "^4.9.1" diff --git a/packages/react-router/test/base/scripts/sync.sh b/packages/react-router/test/base/scripts/sync.sh index 1be037080bd..ad0d879c771 100644 --- a/packages/react-router/test/base/scripts/sync.sh +++ b/packages/react-router/test/base/scripts/sync.sh @@ -15,4 +15,4 @@ npm pack ../../../../react npm pack ../../../ # Install Dependencies -npm install *.tgz --no-save +npm install *.tgz --no-save --legacy-peer-deps diff --git a/packages/react-router/test/base/src/App.test.tsx b/packages/react-router/test/base/src/App.test.tsx index 8c927a8d7ac..b770c1c4d5c 100644 --- a/packages/react-router/test/base/src/App.test.tsx +++ b/packages/react-router/test/base/src/App.test.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { render } from '@testing-library/react'; +import React from 'react'; + import App from './App'; test('renders without crashing', () => { diff --git a/packages/react-router/test/base/src/App.tsx b/packages/react-router/test/base/src/App.tsx index cdfa67d1360..a97c04f5d71 100644 --- a/packages/react-router/test/base/src/App.tsx +++ b/packages/react-router/test/base/src/App.tsx @@ -1,6 +1,6 @@ import { IonApp, setupIonicReact, IonRouterOutlet } from '@ionic/react'; import React from 'react'; -import { Route } from 'react-router-dom'; +import { Route, Navigate } from 'react-router-dom'; /* Core CSS required for Ionic components to work properly */ import '@ionic/react/css/core.css'; @@ -21,22 +21,26 @@ import '@ionic/react/css/text-transformation.css'; /* Theme variables */ import './theme/variables.css'; import Main from './pages/Main'; + import { IonReactRouter } from '@ionic/react-router'; + +import DynamicIonpageClassnames from './pages/dynamic-ionpage-classnames/DynamicIonpageClassnames'; import DynamicRoutes from './pages/dynamic-routes/DynamicRoutes'; -import Routing from './pages/routing/Routing'; -import MultipleTabs from './pages/muiltiple-tabs/MultipleTabs'; import DynamicTabs from './pages/dynamic-tabs/DynamicTabs'; +import MultipleTabs from './pages/muiltiple-tabs/MultipleTabs'; import NestedOutlet from './pages/nested-outlet/NestedOutlet'; import NestedOutlet2 from './pages/nested-outlet/NestedOutlet2'; -import ReplaceAction from './pages/replace-action/Replace'; -import TabsContext from './pages/tab-context/TabContext'; +import NestedParams from './pages/nested-params/NestedParams'; import { OutletRef } from './pages/outlet-ref/OutletRef'; -import { SwipeToGoBack } from './pages/swipe-to-go-back/SwipToGoBack'; +import Params from './pages/params/Params'; import Refs from './pages/refs/Refs'; -import DynamicIonpageClassnames from './pages/dynamic-ionpage-classnames/DynamicIonpageClassnames'; +import { Page1, Page2, Page3 } from './pages/replace-action/Replace'; +import Routing from './pages/routing/Routing'; +import { SwipeToGoBack } from './pages/swipe-to-go-back/SwipToGoBack'; +import TabsContext from './pages/tab-context/TabContext'; import Tabs from './pages/tabs/Tabs'; import TabsSecondary from './pages/tabs/TabsSecondary'; -import Params from './pages/params/Params'; +import TabHistoryIsolation from './pages/tab-history-isolation/TabHistoryIsolation'; import Overlays from './pages/overlays/Overlays'; setupIonicReact(); @@ -46,23 +50,28 @@ const App: React.FC = () => { - - - - - - - - - - - - - - - - - + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> diff --git a/packages/react-router/test/base/src/index.tsx b/packages/react-router/test/base/src/index.tsx index 5ed41355a40..de6c73b77f4 100644 --- a/packages/react-router/test/base/src/index.tsx +++ b/packages/react-router/test/base/src/index.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { createRoot } from 'react-dom/client'; + import App from './App'; const container = document.getElementById('root'); diff --git a/packages/react-router/test/base/src/pages/Main.tsx b/packages/react-router/test/base/src/pages/Main.tsx index cd4c5f6980c..4f87061e347 100644 --- a/packages/react-router/test/base/src/pages/Main.tsx +++ b/packages/react-router/test/base/src/pages/Main.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { IonContent, IonHeader, @@ -9,15 +8,20 @@ import { IonItem, IonLabel, } from '@ionic/react'; +import React from 'react'; + +import packageJson from '../../package.json'; -interface MainProps {} +const Main: React.FC = () => { + const majorVersion = packageJson.dependencies['react-router'].match( + /(\d+)\.(\d+)\.(\d+)/ + )?.[1]; -const Main: React.FC = () => { return ( - Main + Test App - React Router v{majorVersion} @@ -64,9 +68,15 @@ const Main: React.FC = () => { Tabs + + Tab History Isolation + Params + + Nested Params + diff --git a/packages/react-router/test/base/src/pages/dynamic-ionpage-classnames/DynamicIonpageClassnames.tsx b/packages/react-router/test/base/src/pages/dynamic-ionpage-classnames/DynamicIonpageClassnames.tsx index baba236a0c6..9dbbb6b899c 100644 --- a/packages/react-router/test/base/src/pages/dynamic-ionpage-classnames/DynamicIonpageClassnames.tsx +++ b/packages/react-router/test/base/src/pages/dynamic-ionpage-classnames/DynamicIonpageClassnames.tsx @@ -1,4 +1,3 @@ -import React, { useEffect, useRef, useState } from 'react'; import { IonButton, IonContent, @@ -8,14 +7,13 @@ import { IonTitle, IonToolbar, } from '@ionic/react'; +import React, { useEffect, useRef, useState } from 'react'; import { Route } from 'react-router'; -interface DynamicIonpageClassnamesProps {} - -const DynamicIonpageClassnames: React.FC = () => { +const DynamicIonpageClassnames: React.FC = () => { return ( - + } /> ); }; @@ -27,8 +25,9 @@ const Page: React.FC = (props) => { const [divClasses, setDivClasses] = useState(); const ref = useRef(); useEffect(() => { + let observer: MutationObserver | undefined; if(ref.current) { - var observer = new MutationObserver(function (event) { + observer = new MutationObserver(function (event) { setDivClasses(ref.current?.className) }) @@ -39,7 +38,7 @@ const Page: React.FC = (props) => { characterData: false }) } - return () => observer.disconnect() + return () => observer?.disconnect() }, []) diff --git a/packages/react-router/test/base/src/pages/dynamic-routes/DynamicRoutes.tsx b/packages/react-router/test/base/src/pages/dynamic-routes/DynamicRoutes.tsx index 89a598c4636..f91da67b4ff 100644 --- a/packages/react-router/test/base/src/pages/dynamic-routes/DynamicRoutes.tsx +++ b/packages/react-router/test/base/src/pages/dynamic-routes/DynamicRoutes.tsx @@ -1,4 +1,3 @@ -import React, { useState, ReactElement } from 'react'; import { IonContent, IonHeader, @@ -7,32 +6,33 @@ import { IonToolbar, IonRouterOutlet, } from '@ionic/react'; -import { Route, Redirect } from 'react-router'; +import React, { useState } from 'react'; +import type { ReactElement } from 'react'; +import { Route, Navigate } from 'react-router'; import { Link } from 'react-router-dom'; const DynamicRoutes: React.FC = () => { + const addRoute = () => { + const newRoute = ( + } /> + ); + setRoutes([...routes, newRoute]); + }; + const [routes, setRoutes] = useState([ } - exact={true} + element={} />, ]); - const addRoute = () => { - const newRoute = ( - - ); - setRoutes([...routes, newRoute]); - }; - return ( {routes} - {/* } /> */} - } /> - } /> + {/* } /> */} + } /> + } /> ); }; diff --git a/packages/react-router/test/base/src/pages/dynamic-tabs/DynamicTabs.tsx b/packages/react-router/test/base/src/pages/dynamic-tabs/DynamicTabs.tsx index 5f2203dd389..cb1079328a8 100644 --- a/packages/react-router/test/base/src/pages/dynamic-tabs/DynamicTabs.tsx +++ b/packages/react-router/test/base/src/pages/dynamic-tabs/DynamicTabs.tsx @@ -1,11 +1,9 @@ -import React, { useState, useCallback } from 'react'; import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, - IonApp, IonTabs, IonRouterOutlet, IonTabBar, @@ -14,56 +12,36 @@ import { IonLabel, IonButton, } from '@ionic/react'; -import { Route, Redirect } from 'react-router'; -import { IonReactRouter } from '@ionic/react-router'; import { triangle, square } from 'ionicons/icons'; +import React, { useState, useCallback } from 'react'; +import { Route, Navigate } from 'react-router'; const DynamicTabs: React.FC = () => { const [display2ndTab, setDisplayThirdTab] = useState(false); - const renderFirstTab = useCallback(() => { - return setDisplayThirdTab(!display2ndTab)} />; - }, [display2ndTab]); - - const render2ndTabRoute = useCallback(() => { - if (display2ndTab) { - return ; - } else { - // This is weird, if I return null or undefined then I get all sorts of errors, seemingly - // because the router is mad about a child not being a route. - return ; - } - }, [display2ndTab]); - return ( - - - - - - {render2ndTabRoute()} - } - exact={true} - /> - } /> - - - - - Tab 1 - - {display2ndTab && ( - - - Tab 2 - - )} - - - - + + + } /> + : } + /> + } /> + + + + + Tab 1 + + {display2ndTab && ( + + + Tab 2 + + )} + + ); }; diff --git a/packages/react-router/test/base/src/pages/muiltiple-tabs/Menu.tsx b/packages/react-router/test/base/src/pages/muiltiple-tabs/Menu.tsx index dbde2166f6d..92f8e378b86 100644 --- a/packages/react-router/test/base/src/pages/muiltiple-tabs/Menu.tsx +++ b/packages/react-router/test/base/src/pages/muiltiple-tabs/Menu.tsx @@ -1,5 +1,6 @@ -import React from 'react'; import { IonMenu, IonContent, IonList, IonItem, IonLabel, IonMenuToggle } from '@ionic/react'; +import React from 'react'; + export const Menu: React.FC = () => { return ( diff --git a/packages/react-router/test/base/src/pages/muiltiple-tabs/MultipleTabs.tsx b/packages/react-router/test/base/src/pages/muiltiple-tabs/MultipleTabs.tsx index a0efdf560fd..5ccc4c371ad 100644 --- a/packages/react-router/test/base/src/pages/muiltiple-tabs/MultipleTabs.tsx +++ b/packages/react-router/test/base/src/pages/muiltiple-tabs/MultipleTabs.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { IonSplitPane, IonRouterOutlet, @@ -15,10 +14,12 @@ import { IonTitle, IonToolbar, } from '@ionic/react'; +import { triangle, ellipse, square, rocket } from 'ionicons/icons'; +import React from 'react'; +import { Route, Navigate } from 'react-router'; -import { Route, Redirect } from 'react-router'; import { Menu } from './Menu'; -import { triangle, ellipse, square, rocket } from 'ionicons/icons'; + const MultipleTabs: React.FC = () => { return ( @@ -26,24 +27,14 @@ const MultipleTabs: React.FC = () => { { - return ; - }} - exact={false} - /> - { - return ; - }} - exact={false} + path="/multiple-tabs/tab1/*" + element={} /> } - exact={true} + path="/multiple-tabs/tab2/*" + element={} /> + } /> ); @@ -68,12 +59,11 @@ const Tab1: React.FC = () => { } - exact={true} + element={} /> - {/* */} - } exact={true} /> - } exact={true} /> + {/* } /> */} + } /> + } /> ); @@ -95,12 +85,11 @@ const Tab2: React.FC = () => { } - exact={true} + element={} /> - {/* */} - } exact={true} /> - } exact={true} /> + {/* } /> */} + } /> + } /> ); diff --git a/packages/react-router/test/base/src/pages/nested-outlet/NestedOutlet.tsx b/packages/react-router/test/base/src/pages/nested-outlet/NestedOutlet.tsx index 62aa9e1e7f6..a3ca6da2027 100644 --- a/packages/react-router/test/base/src/pages/nested-outlet/NestedOutlet.tsx +++ b/packages/react-router/test/base/src/pages/nested-outlet/NestedOutlet.tsx @@ -7,9 +7,8 @@ import { IonTitle, IonToolbar, } from '@ionic/react'; -import { useEffect } from 'react'; -import React from 'react'; -import { Route, Redirect } from 'react-router'; +import React, { useEffect } from 'react'; +import { Route, Navigate } from 'react-router'; const Page: React.FC = () => { useEffect(() => { @@ -48,10 +47,9 @@ const SecondPage: React.FC = () => { } + element={} /> - + } /> ); }; @@ -81,8 +79,8 @@ const FirstPage: React.FC = () => { const NestedOutlet: React.FC = () => ( - - + } /> + } /> ); diff --git a/packages/react-router/test/base/src/pages/nested-outlet/NestedOutlet2.tsx b/packages/react-router/test/base/src/pages/nested-outlet/NestedOutlet2.tsx index d62911046c8..dcd6d6cfa97 100644 --- a/packages/react-router/test/base/src/pages/nested-outlet/NestedOutlet2.tsx +++ b/packages/react-router/test/base/src/pages/nested-outlet/NestedOutlet2.tsx @@ -1,5 +1,3 @@ -import React from 'react'; -import { Redirect, Route, RouteComponentProps } from 'react-router-dom'; import { IonBackButton, IonButtons, @@ -13,12 +11,14 @@ import { IonTitle, IonToolbar, } from '@ionic/react'; +import React from 'react'; +import { Navigate, Route, useParams } from 'react-router-dom'; -const ListPage: React.FC = ({ match }) => { +const ListPage: React.FC = () => { return ( - - + } /> + } /> ); }; @@ -51,7 +51,9 @@ const List: React.FC = () => { ); }; -const Item: React.FC> = ({ match }) => { +const Item: React.FC = () => { + const { id } = useParams<{ id: string }>(); + return ( @@ -62,16 +64,16 @@ const Item: React.FC> = ({ match }) => { Item - Detail of item #{match.params.id} + Detail of item #{id} ); }; -const HomePage: React.FC = ({ match }) => { +const HomePage: React.FC = () => { return ( - - + } /> + } /> ); }; @@ -98,7 +100,7 @@ const Welcome: React.FC = () => { ); }; -const Home: React.FC> = ({ match }) => { +const Home: React.FC = () => { return ( @@ -122,12 +124,11 @@ const Home: React.FC> = ({ match }) => { const NestedOutlet2: React.FC = () => ( - - + } /> + } /> } - exact={true} + element={} /> ); diff --git a/packages/react-router/test/base/src/pages/nested-params/NestedParams.tsx b/packages/react-router/test/base/src/pages/nested-params/NestedParams.tsx new file mode 100644 index 00000000000..a92f5253062 --- /dev/null +++ b/packages/react-router/test/base/src/pages/nested-params/NestedParams.tsx @@ -0,0 +1,110 @@ +import { + IonButton, + IonContent, + IonHeader, + IonLabel, + IonPage, + IonRouterOutlet, + IonTitle, + IonToolbar, +} from '@ionic/react'; +import React from 'react'; +import { Navigate, Route } from 'react-router'; +import { useParams } from 'react-router-dom'; + +const NestedParamsRoot: React.FC = () => ( + + + + Nested Params + + + + + } /> + } /> + + + +); + +const Landing: React.FC = () => ( + + + + Select a User + + + + A nested route will try to read the parent :userId parameter. + + Go to User 42 Details + + + Go to User 99 Details + + + +); + +const UserLayout: React.FC = () => { + const { userId } = useParams<{ userId: string }>(); + + return ( + + + + User {userId ?? 'missing'} + + + + Layout sees user: {userId ?? 'missing'} + + } /> + } /> + } /> + + + + ); +}; + +const UserDetails: React.FC = () => { + const { userId } = useParams<{ userId: string }>(); + + return ( + + + + Details + + + + Details view user: {userId ?? 'missing'} + + Go to Settings + + + + ); +}; + +const UserSettings: React.FC = () => { + const { userId } = useParams<{ userId: string }>(); + + return ( + + + + Settings + + + + Settings view user: {userId ?? 'missing'} + Back to Details + + + ); +}; + +export default NestedParamsRoot; diff --git a/packages/react-router/test/base/src/pages/outlet-ref/OutletRef.tsx b/packages/react-router/test/base/src/pages/outlet-ref/OutletRef.tsx index 9aa3e9e0ba9..53c9c2ffebc 100644 --- a/packages/react-router/test/base/src/pages/outlet-ref/OutletRef.tsx +++ b/packages/react-router/test/base/src/pages/outlet-ref/OutletRef.tsx @@ -1,4 +1,3 @@ -import React, { useRef, useEffect } from 'react'; import { IonRouterOutlet, IonPage, @@ -7,24 +6,25 @@ import { IonTitle, IonContent, } from '@ionic/react'; +import React, { useRef, useEffect, useState } from 'react'; import { Route } from 'react-router'; -interface OutletRefProps {} - -export const OutletRef: React.FC = () => { +export const OutletRef: React.FC = () => { const ref = useRef(null); + const [outletId, setOutletId] = useState(undefined); useEffect(() => { - console.log(ref); + // Update the outlet id once the ref is populated + if (ref.current?.id) { + setOutletId(ref.current.id); + } }, []); return ( { - return
; - }} + element={
} /> ); diff --git a/packages/react-router/test/base/src/pages/overlays/Overlays.tsx b/packages/react-router/test/base/src/pages/overlays/Overlays.tsx index 9343df83b97..19fe9575bb8 100644 --- a/packages/react-router/test/base/src/pages/overlays/Overlays.tsx +++ b/packages/react-router/test/base/src/pages/overlays/Overlays.tsx @@ -1,15 +1,15 @@ import { IonButton, IonContent, IonModal } from '@ionic/react'; import { useState } from 'react'; -import { useHistory } from 'react-router'; +import { useNavigate } from 'react-router-dom'; const Overlays: React.FC = () => { const [isOpen, setIsOpen] = useState(false); - const history = useHistory(); + const navigate = useNavigate(); - const goBack = () => history.goBack(); - const replace = () => history.replace('/'); - const push = () => history.push('/'); + const goBack = () => navigate(-1); + const replace = () => navigate('/', { replace: true }); + const push = () => navigate('/'); return ( <> diff --git a/packages/react-router/test/base/src/pages/params/Params.tsx b/packages/react-router/test/base/src/pages/params/Params.tsx index 18f49d45888..b60903bb1c3 100644 --- a/packages/react-router/test/base/src/pages/params/Params.tsx +++ b/packages/react-router/test/base/src/pages/params/Params.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { IonButtons, IonBackButton, @@ -9,30 +8,29 @@ import { IonTitle, IonToolbar, } from '@ionic/react'; -import { RouteComponentProps } from 'react-router'; - -interface PageProps -extends RouteComponentProps<{ - id: string; -}> {} +import React from 'react'; +import { useParams } from 'react-router-dom'; +const Page: React.FC = () => { + const { id } = useParams<{ id: string }>(); + const parseID = id ? parseInt(id) : NaN; + const displayId = id || 'N/A'; + const nextParamLink = !isNaN(parseID) ? `/params/${parseID + 1}` : '/params/1'; -const Page: React.FC = ({ match }) => { - const parseID = parseInt(match.params.id); return ( - + - Params { match.params.id } + Params { displayId } - Go to next param + Go to next param
- Page ID: { match.params.id } + Page ID: { displayId }
); diff --git a/packages/react-router/test/base/src/pages/refs/Refs.tsx b/packages/react-router/test/base/src/pages/refs/Refs.tsx index 7ac15c83ab3..9b20848e9fc 100644 --- a/packages/react-router/test/base/src/pages/refs/Refs.tsx +++ b/packages/react-router/test/base/src/pages/refs/Refs.tsx @@ -1,27 +1,26 @@ -import React, { useRef } from "react"; import { IonContent, IonHeader, IonPage, IonRouterOutlet, IonTitle, + IonText, IonToolbar, } from "@ionic/react"; +import React, { useRef } from "react"; import { Route } from "react-router"; -interface RefsProps {} - const Refs: React.FC = () => { return ( - {/* } /> */} - - + {/* } /> */} + } /> + } /> ); }; -const RefsFC: React.FC = () => { +const RefsFC: React.FC = () => { const contentRef = useRef(null); return ( @@ -30,7 +29,11 @@ const RefsFC: React.FC = () => { Refs FC - + + +

This view is used for automated ref regression tests.

+
+
); }; @@ -45,7 +48,11 @@ class RefsClass extends React.Component { Refs Class - + + +

This view is used for automated ref regression tests.

+
+
); } diff --git a/packages/react-router/test/base/src/pages/replace-action/Replace.tsx b/packages/react-router/test/base/src/pages/replace-action/Replace.tsx index 2f4e3f38de7..5ec4b53d30b 100644 --- a/packages/react-router/test/base/src/pages/replace-action/Replace.tsx +++ b/packages/react-router/test/base/src/pages/replace-action/Replace.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { IonContent, IonHeader, @@ -6,24 +5,15 @@ import { IonTitle, IonToolbar, IonButton, - IonRouterOutlet, IonButtons, IonBackButton, } from '@ionic/react'; -import { Route, Redirect, useHistory } from 'react-router'; - -interface TopPageProps {} +import React from 'react'; +import { useNavigate } from 'react-router-dom'; -const ReplaceAction: React.FC = () => { - return ( - - - - - } /> - - ); -}; +// ReplaceAction is no longer used as a component wrapper +// Routes are defined directly in App.tsx +const ReplaceAction: React.FC = () => null; const Page1: React.FC = () => ( @@ -42,10 +32,10 @@ const Page1: React.FC = () => ( ); const Page2: React.FC = () => { - const history = useHistory(); + const navigate = useNavigate(); const clickButton = () => { - history.replace('/replace-action/page3'); + navigate('/replace-action/page3', { replace: true }); }; return ( @@ -84,3 +74,4 @@ const Page3: React.FC = () => { }; export default ReplaceAction; +export { Page1, Page2, Page3 }; diff --git a/packages/react-router/test/base/src/pages/routing/Details.tsx b/packages/react-router/test/base/src/pages/routing/Details.tsx index 94aeeb6dbaf..5e97a48cae3 100644 --- a/packages/react-router/test/base/src/pages/routing/Details.tsx +++ b/packages/react-router/test/base/src/pages/routing/Details.tsx @@ -1,4 +1,3 @@ -import React, { useEffect } from 'react'; import { IonContent, IonHeader, @@ -10,11 +9,10 @@ import { IonLabel, IonButton, } from '@ionic/react'; -import { useParams, useLocation } from 'react-router'; - -interface DetailsProps {} +import React, { useEffect } from 'react'; +import { useParams, useLocation } from 'react-router-dom'; -const Details: React.FC = () => { +const Details: React.FC = () => { const { id } = useParams<{ id: string }>(); const location = useLocation(); @@ -24,7 +22,7 @@ const Details: React.FC = () => { return () => console.log('Home Details unmount'); }, []); - const nextId = parseInt(id, 10) + 1; + const nextId = parseInt(id ?? '0', 10) + 1; return ( diff --git a/packages/react-router/test/base/src/pages/routing/Favorites.tsx b/packages/react-router/test/base/src/pages/routing/Favorites.tsx index 7a3c80d2e39..7c8b9cb1142 100644 --- a/packages/react-router/test/base/src/pages/routing/Favorites.tsx +++ b/packages/react-router/test/base/src/pages/routing/Favorites.tsx @@ -1,4 +1,3 @@ -import React, { useEffect } from 'react'; import { IonContent, IonHeader, @@ -9,10 +8,9 @@ import { IonMenuButton, useIonViewWillEnter, } from '@ionic/react'; +import React, { useEffect } from 'react'; -interface FavoritesProps {} - -const Favorites: React.FC = () => { +const Favorites: React.FC = () => { useIonViewWillEnter(() => { console.log('IVWE on Favorites'); }); diff --git a/packages/react-router/test/base/src/pages/routing/Menu.tsx b/packages/react-router/test/base/src/pages/routing/Menu.tsx index d53d9ad0a70..763a31a56bd 100644 --- a/packages/react-router/test/base/src/pages/routing/Menu.tsx +++ b/packages/react-router/test/base/src/pages/routing/Menu.tsx @@ -8,10 +8,8 @@ import { IonMenu, IonMenuToggle, } from '@ionic/react'; -import React from 'react'; import { heartOutline, heartSharp, mailOutline, mailSharp } from 'ionicons/icons'; - -interface MenuProps {} +import React from 'react'; interface AppPage { url: string; @@ -53,7 +51,7 @@ const appPages: AppPage[] = [ }, ]; -const Menu: React.FunctionComponent = () => { +const Menu: React.FunctionComponent = () => { return ( diff --git a/packages/react-router/test/base/src/pages/routing/OtherPage.tsx b/packages/react-router/test/base/src/pages/routing/OtherPage.tsx index 6f1138329fc..b1e452e9bb0 100644 --- a/packages/react-router/test/base/src/pages/routing/OtherPage.tsx +++ b/packages/react-router/test/base/src/pages/routing/OtherPage.tsx @@ -1,4 +1,3 @@ -import React, { useEffect } from 'react'; import { IonContent, IonHeader, @@ -10,10 +9,9 @@ import { useIonViewWillEnter, IonButton, } from '@ionic/react'; +import React, { useEffect } from 'react'; -interface OtherPageProps {} - -const OtherPage: React.FC = () => { +const OtherPage: React.FC = () => { useIonViewWillEnter(() => { console.log('IVWE on otherpage'); }); @@ -25,7 +23,7 @@ const OtherPage: React.FC = () => { return ( // - // ( + // @@ -39,7 +37,7 @@ const OtherPage: React.FC = () => { Go to tab3 - // )}> + // }> // ); }; diff --git a/packages/react-router/test/base/src/pages/routing/PropsTest.tsx b/packages/react-router/test/base/src/pages/routing/PropsTest.tsx index d8cc386a1b8..a0d33c238e6 100644 --- a/packages/react-router/test/base/src/pages/routing/PropsTest.tsx +++ b/packages/react-router/test/base/src/pages/routing/PropsTest.tsx @@ -1,4 +1,3 @@ -import React, { useState, useEffect } from 'react'; import { IonContent, IonHeader, @@ -8,11 +7,10 @@ import { IonButton, IonRouterOutlet, } from '@ionic/react'; +import React, { useState, useEffect } from 'react'; import { Route } from 'react-router'; -interface PropsTestProps {} - -const PropsTest: React.FC = () => { +const PropsTest: React.FC = () => { const [count, setCount] = useState(1); useEffect(() => { console.log(count); @@ -21,7 +19,7 @@ const PropsTest: React.FC = () => { } + element={} /> ); diff --git a/packages/react-router/test/base/src/pages/routing/RedirectRouting.tsx b/packages/react-router/test/base/src/pages/routing/RedirectRouting.tsx index cd63689b779..559cf6a9d4f 100644 --- a/packages/react-router/test/base/src/pages/routing/RedirectRouting.tsx +++ b/packages/react-router/test/base/src/pages/routing/RedirectRouting.tsx @@ -1,5 +1,6 @@ -import React, { useEffect, useContext } from 'react'; import { IonRouterContext } from '@ionic/react'; +import type React from 'react'; +import { useEffect, useContext } from 'react'; const RedirectRouting: React.FC = () => { const ionRouterContext = useContext(IonRouterContext); diff --git a/packages/react-router/test/base/src/pages/routing/Routing.tsx b/packages/react-router/test/base/src/pages/routing/Routing.tsx index 5fcf7c133fc..ef9cf5dc4a6 100644 --- a/packages/react-router/test/base/src/pages/routing/Routing.tsx +++ b/packages/react-router/test/base/src/pages/routing/Routing.tsx @@ -1,57 +1,43 @@ -import React from 'react'; import { IonContent, IonPage, IonRouterOutlet, IonSplitPane, } from '@ionic/react'; -import Menu from './Menu'; -import { Route, Redirect } from 'react-router'; -import Tabs from './Tabs'; +import React from 'react'; +import { Route, Navigate } from 'react-router'; + import Favorites from './Favorites'; +import Menu from './Menu'; import OtherPage from './OtherPage'; import PropsTest from './PropsTest'; import RedirectRouting from './RedirectRouting'; +import Tabs from './Tabs'; -interface RoutingProps {} - -const Routing: React.FC = () => { +const Routing: React.FC = () => { return ( - } /> - {/* */} - } exact /> - - {/* { - return ( - - - - ); - }} /> */} - {/* { - return ( - - - - ); - }} /> */} - - - } /> - } /> + } /> + + } /> + } /> + } /> + } /> + } /> + } /> + ( + path="*" + element={ -
Not found
+
Not found in routing.tsx
- )} + } /> - {/* } /> */}
); diff --git a/packages/react-router/test/base/src/pages/routing/SettingsDetails.tsx b/packages/react-router/test/base/src/pages/routing/SettingsDetails.tsx index 0dc5b0be6ff..335aefbf8c3 100644 --- a/packages/react-router/test/base/src/pages/routing/SettingsDetails.tsx +++ b/packages/react-router/test/base/src/pages/routing/SettingsDetails.tsx @@ -1,4 +1,3 @@ -import React, { useEffect } from 'react'; import { IonContent, IonHeader, @@ -10,11 +9,10 @@ import { IonLabel, IonButton, } from '@ionic/react'; -import { useParams } from 'react-router'; - -interface DetailsProps {} +import React, { useEffect } from 'react'; +import { useParams } from 'react-router-dom'; -const SettingsDetails: React.FC = () => { +const SettingsDetails: React.FC = () => { const { id } = useParams<{ id: string }>(); useEffect(() => { @@ -22,7 +20,7 @@ const SettingsDetails: React.FC = () => { return () => console.log('Settings Details unmount'); }, []); - const nextId = parseInt(id, 10) + 1; + const nextId = parseInt(id ?? '0', 10) + 1; // LEFT OFF - why is back button not working for multiple entries? return ( diff --git a/packages/react-router/test/base/src/pages/routing/Tab1.tsx b/packages/react-router/test/base/src/pages/routing/Tab1.tsx index bf14ce1456d..d9e204d55ad 100644 --- a/packages/react-router/test/base/src/pages/routing/Tab1.tsx +++ b/packages/react-router/test/base/src/pages/routing/Tab1.tsx @@ -1,4 +1,3 @@ -import React, { useEffect, useContext } from 'react'; import { IonContent, IonHeader, @@ -14,6 +13,7 @@ import { IonButton, IonRouterContext, } from '@ionic/react'; +import React, { useEffect, useContext } from 'react'; import './Tab1.css'; import { Link } from 'react-router-dom'; @@ -54,8 +54,8 @@ const Tab1: React.FC = () => { Details 1 - - Details 1 & Unmount + + Details 1 (alt) Details 1 with Query Params diff --git a/packages/react-router/test/base/src/pages/routing/Tab2.tsx b/packages/react-router/test/base/src/pages/routing/Tab2.tsx index a6437dec41f..7d86d13933c 100644 --- a/packages/react-router/test/base/src/pages/routing/Tab2.tsx +++ b/packages/react-router/test/base/src/pages/routing/Tab2.tsx @@ -1,4 +1,3 @@ -import React, { useEffect } from 'react'; import { IonContent, IonHeader, @@ -12,11 +11,12 @@ import { IonMenuButton, IonButton, } from '@ionic/react'; +import React, { useEffect } from 'react'; import './Tab2.css'; -import { useHistory } from 'react-router'; +import { useNavigate } from 'react-router-dom'; const Tab2: React.FC = () => { - const history = useHistory(); + const navigate = useNavigate(); useEffect(() => { console.log('Settings mount'); @@ -51,10 +51,10 @@ const Tab2: React.FC = () => {
{ - history.push('/routing/tabs/settings/details/1', { routerOptions: { unmount: true } }); + navigate('/routing/tabs/settings/details/1'); }} > - Details with Unmount via history.push + Details with Unmount via navigate diff --git a/packages/react-router/test/base/src/pages/routing/Tab3.tsx b/packages/react-router/test/base/src/pages/routing/Tab3.tsx index d4564de0a37..d05a3ab9bc6 100644 --- a/packages/react-router/test/base/src/pages/routing/Tab3.tsx +++ b/packages/react-router/test/base/src/pages/routing/Tab3.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { IonContent, IonHeader, @@ -10,6 +9,7 @@ import { IonMenuButton, IonButton, } from '@ionic/react'; +import React from 'react'; import './Tab3.css'; class Tab3 extends React.Component { diff --git a/packages/react-router/test/base/src/pages/routing/Tabs.tsx b/packages/react-router/test/base/src/pages/routing/Tabs.tsx index 3ded8d9ee99..d70ffd7caaf 100644 --- a/packages/react-router/test/base/src/pages/routing/Tabs.tsx +++ b/packages/react-router/test/base/src/pages/routing/Tabs.tsx @@ -1,41 +1,40 @@ +import { IonTabs, IonRouterOutlet, IonTabBar, IonTabButton, IonIcon, IonLabel, IonPage, IonContent } from '@ionic/react'; +import { triangle, ellipse, square } from 'ionicons/icons'; import React from 'react'; -import { IonTabs, IonRouterOutlet, IonTabBar, IonTabButton, IonIcon, IonLabel } from '@ionic/react'; -import { Route, Redirect } from 'react-router'; -import Tab1 from './Tab1'; +import { Route, Navigate } from 'react-router'; + import Details from './Details'; +import SettingsDetails from './SettingsDetails'; +import Tab1 from './Tab1'; import Tab2 from './Tab2'; import Tab3 from './Tab3'; -import { triangle, ellipse, square } from 'ionicons/icons'; -import SettingsDetails from './SettingsDetails'; -interface TabsProps {} -const Tabs: React.FC = () => { + +const Tabs: React.FC = () => { return ( - - - {/* { - return
- }} exact={true} /> */} - - - - } - exact={true} - /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> } - exact={true} + path="*" + element={ + + +
Not found in tabs.tsx
+
+
+ } /> - {/* } />} /> */} - + Home diff --git a/packages/react-router/test/base/src/pages/swipe-to-go-back/SwipToGoBack.tsx b/packages/react-router/test/base/src/pages/swipe-to-go-back/SwipToGoBack.tsx index 2b88551b85e..72fed8f819f 100644 --- a/packages/react-router/test/base/src/pages/swipe-to-go-back/SwipToGoBack.tsx +++ b/packages/react-router/test/base/src/pages/swipe-to-go-back/SwipToGoBack.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { IonRouterOutlet, IonPage, @@ -10,15 +9,14 @@ import { IonButtons, IonBackButton, } from '@ionic/react'; +import React from 'react'; import { Route } from 'react-router'; -interface SwipeToGoBackProps {} - -export const SwipeToGoBack: React.FC = () => { +export const SwipeToGoBack: React.FC = () => { return ( - - + } /> + } /> ); }; diff --git a/packages/react-router/test/base/src/pages/tab-context/TabContext.tsx b/packages/react-router/test/base/src/pages/tab-context/TabContext.tsx index b89cface216..e200f1e8112 100644 --- a/packages/react-router/test/base/src/pages/tab-context/TabContext.tsx +++ b/packages/react-router/test/base/src/pages/tab-context/TabContext.tsx @@ -1,4 +1,3 @@ -import React, { useContext } from 'react'; import { IonTabs, IonRouterOutlet, @@ -16,21 +15,20 @@ import { IonTabsContext, IonButton, } from '@ionic/react'; -import { Route, Redirect } from 'react-router'; import { triangle, square } from 'ionicons/icons'; +import React, { useContext } from 'react'; +import { Route, Navigate } from 'react-router'; -interface TabsContextProps {} - -const TabsContext: React.FC = () => { +const TabsContext: React.FC = () => { return ( - - - + } /> + } /> + } /> - + Tab1 diff --git a/packages/react-router/test/base/src/pages/tab-history-isolation/TabHistoryIsolation.tsx b/packages/react-router/test/base/src/pages/tab-history-isolation/TabHistoryIsolation.tsx new file mode 100644 index 00000000000..a3ea324c85c --- /dev/null +++ b/packages/react-router/test/base/src/pages/tab-history-isolation/TabHistoryIsolation.tsx @@ -0,0 +1,162 @@ +import { + IonTabs, + IonRouterOutlet, + IonTabBar, + IonTabButton, + IonIcon, + IonLabel, + IonPage, + IonHeader, + IonToolbar, + IonButtons, + IonBackButton, + IonTitle, + IonContent, + IonButton, +} from '@ionic/react'; +import { triangle, square, ellipse } from 'ionicons/icons'; +import React from 'react'; +import { Route, Navigate } from 'react-router'; + +const TabHistoryIsolation: React.FC = () => { + return ( + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + + Tab A + + + + Tab B + + + + Tab C + + + + ); +}; + +const TabA = () => { + return ( + + + + + + + Tab A + + + + Tab A + + Go to A Details + + + + ); +}; + +const TabB = () => { + return ( + + + + + + + Tab B + + + + Tab B + + Go to B Details + + + + ); +}; + +const TabC = () => { + return ( + + + + + + + Tab C + + + + Tab C + + Go to C Details + + + + ); +}; + +const TabADetails = () => { + return ( + + + + + + + Tab A Details + + + Tab A Details + + ); +}; + +const TabBDetails = () => { + return ( + + + + + + + Tab B Details + + + Tab B Details + + ); +}; + +const TabCDetails = () => { + return ( + + + + + + + Tab C Details + + + Tab C Details + + ); +}; + +export default TabHistoryIsolation; diff --git a/packages/react-router/test/base/src/pages/tabs/Tabs.tsx b/packages/react-router/test/base/src/pages/tabs/Tabs.tsx index d27907821d9..3f887829be9 100644 --- a/packages/react-router/test/base/src/pages/tabs/Tabs.tsx +++ b/packages/react-router/test/base/src/pages/tabs/Tabs.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { IonTabs, IonRouterOutlet, @@ -15,20 +14,19 @@ import { IonContent, IonButton, } from '@ionic/react'; -import { Route, Redirect } from 'react-router'; import { triangle, square } from 'ionicons/icons'; +import React from 'react'; +import { Route, Navigate } from 'react-router'; -interface TabsProps {} - -const Tabs: React.FC = () => { +const Tabs: React.FC = () => { return ( - - - - - + } /> + } /> + } /> + } /> + } /> diff --git a/packages/react-router/test/base/src/pages/tabs/TabsSecondary.tsx b/packages/react-router/test/base/src/pages/tabs/TabsSecondary.tsx index ab4103340d0..0df9a12460f 100644 --- a/packages/react-router/test/base/src/pages/tabs/TabsSecondary.tsx +++ b/packages/react-router/test/base/src/pages/tabs/TabsSecondary.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { IonTabs, IonRouterOutlet, @@ -14,18 +13,17 @@ import { IonTitle, IonContent, } from '@ionic/react'; -import { Route, Redirect } from 'react-router'; import { triangle, square } from 'ionicons/icons'; +import React from 'react'; +import { Route, Navigate } from 'react-router'; -interface TabsSecondaryProps {} - -const TabsSecondary: React.FC = () => { +const TabsSecondary: React.FC = () => { return ( - - - + } /> + } /> + } /> diff --git a/packages/react-router/test/base/src/react-app-env.d.ts b/packages/react-router/test/base/src/react-app-env.d.ts index 1f35a7e91aa..9a8fcf86803 100644 --- a/packages/react-router/test/base/src/react-app-env.d.ts +++ b/packages/react-router/test/base/src/react-app-env.d.ts @@ -40,7 +40,7 @@ declare module '*.webp' { } declare module '*.svg' { - import * as React from 'react'; + import type * as React from 'react'; export const ReactComponent: React.FunctionComponent< React.SVGProps & { title?: string } diff --git a/packages/react-router/test/base/src/utils/LocationHistory.ts b/packages/react-router/test/base/src/utils/LocationHistory.ts deleted file mode 100644 index ec5eee44ef6..00000000000 --- a/packages/react-router/test/base/src/utils/LocationHistory.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Location as HistoryLocation } from 'history'; - -const RESTRICT_SIZE = 25; - -export class LocationHistory { - private locationHistory: HistoryLocation[] = []; - - add(location: HistoryLocation) { - this.locationHistory.push(location); - if (this.locationHistory.length > RESTRICT_SIZE) { - this.locationHistory.splice(0, 10); - } - } - - pop() { - this.locationHistory.pop(); - } - - replace(location: HistoryLocation) { - this.locationHistory.pop(); - this.locationHistory.push(location); - } - - clear() { - this.locationHistory = []; - } - - findLastLocationByUrl(url: string) { - for (let i = this.locationHistory.length - 1; i >= 0; i--) { - const location = this.locationHistory[i]; - if (location.pathname.toLocaleLowerCase() === url.toLocaleLowerCase()) { - return location; - } - } - return undefined; - } - - previous() { - return this.locationHistory[this.locationHistory.length - 2]; - } - - current() { - return this.locationHistory[this.locationHistory.length - 1]; - } -} diff --git a/packages/react-router/test/base/src/utils/generateId.ts b/packages/react-router/test/base/src/utils/generateId.ts index 06bb0a39a6f..6a37c44c6ed 100644 --- a/packages/react-router/test/base/src/utils/generateId.ts +++ b/packages/react-router/test/base/src/utils/generateId.ts @@ -1,7 +1,7 @@ const ids: { [key: string]: number } = { main: 1 }; -export const generateId = (type: string = 'main') => { - let id = (ids[type] ?? 1) + 1; +export const generateId = (type = 'main') => { + const id = (ids[type] ?? 1) + 1; ids[type] = id; return id.toString(); }; diff --git a/packages/react-router/test/base/tests/e2e/plugins/index.js b/packages/react-router/test/base/tests/e2e/plugins/index.js index 8dd144a6c1a..a9fbe480369 100644 --- a/packages/react-router/test/base/tests/e2e/plugins/index.js +++ b/packages/react-router/test/base/tests/e2e/plugins/index.js @@ -18,4 +18,5 @@ module.exports = (on, config) => { // `on` is used to hook into various events Cypress emits // `config` is the resolved Cypress config + require('cypress-terminal-report/src/installLogsPrinter')(on); }; diff --git a/packages/react-router/test/base/tests/e2e/specs/cross-route-navigation.cy.js b/packages/react-router/test/base/tests/e2e/specs/cross-route-navigation.cy.js new file mode 100644 index 00000000000..e3b57ac7009 --- /dev/null +++ b/packages/react-router/test/base/tests/e2e/specs/cross-route-navigation.cy.js @@ -0,0 +1,168 @@ +const port = 3000; + +describe('Cross-Route Navigation', () => { + /** + * This test verifies that navigation between different top-level routes works correctly. + * + * Routing uses and MultipleTabs uses + * , ensuring view isolation between outlets. + */ + it('should navigate from home to routing and back correctly', () => { + // Start at home + cy.visit(`http://localhost:${port}/`); + cy.ionPageVisible('home'); + + // Navigate to routing by clicking the link + cy.contains('ion-item', 'Routing').click(); + + // Routing should redirect to /routing/tabs/home and show the home-page + cy.ionPageVisible('home-page'); + + // Go back to the main home page using browser back + cy.go('back'); + + // Home page should be visible again + cy.ionPageVisible('home'); + }); + + it('should navigate from home to multiple-tabs correctly', () => { + // Start at home + cy.visit(`http://localhost:${port}/`); + cy.ionPageVisible('home'); + + // Navigate to multiple-tabs + cy.contains('ion-item', 'Multiple Tabs').click(); + + // Multiple tabs should redirect to /multiple-tabs/tab1/pagea and show PageA + cy.ionPageVisible('PageA'); + }); + + it('should navigate home -> routing -> back -> routing again', () => { + // Start at home + cy.visit(`http://localhost:${port}/`); + cy.ionPageVisible('home'); + + // Navigate to routing + cy.contains('ion-item', 'Routing').click(); + cy.ionPageVisible('home-page'); + + // Go back to home + cy.go('back'); + cy.ionPageVisible('home'); + + // Navigate to routing again - Navigate should fire again + cy.contains('ion-item', 'Routing').click(); + cy.ionPageVisible('home-page'); + }); + + it('should navigate home -> multiple-tabs -> back -> multiple-tabs again', () => { + // Start at home + cy.visit(`http://localhost:${port}/`); + cy.ionPageVisible('home'); + + // Navigate to multiple-tabs + cy.contains('ion-item', 'Multiple Tabs').click(); + cy.ionPageVisible('PageA'); + + // Go back to home + cy.go('back'); + cy.ionPageVisible('home'); + + // Navigate to multiple-tabs again - Navigate should fire again + cy.contains('ion-item', 'Multiple Tabs').click(); + cy.ionPageVisible('PageA'); + }); + + /** + * This test verifies behavior when navigating between different top-level routes + * that use separate outlet IDs. With unique outlet IDs, view items are completely + * isolated between outlets, so "stale views" from one outlet don't interfere with + * another outlet. + * + * This test uses ionPageDoesNotExist instead of ionPageHidden because views from + * one route hierarchy (like /routing/*) are completely unmounted (not just hidden) + * when navigating to a different route hierarchy (like /multiple-tabs/*). + */ + it('should navigate home -> routing -> home -> multiple-tabs without stale views', () => { + // Start at home + cy.visit(`http://localhost:${port}/`); + cy.ionPageVisible('home'); + + // Navigate to routing + cy.contains('ion-item', 'Routing').click(); + cy.ionPageVisible('home-page'); + cy.url().should('include', '/routing/tabs/home'); + + // Go back to home + cy.go('back'); + cy.ionPageVisible('home'); + + // Navigate to multiple-tabs - this is where stale views could interfere + cy.contains('ion-item', 'Multiple Tabs').click(); + cy.ionPageVisible('PageA'); + cy.url().should('include', '/multiple-tabs/tab1/pagea'); + + // The routing home-page should NOT exist in the DOM (views are unmounted when leaving route) + cy.ionPageDoesNotExist('home-page'); + }); + + /** + * Test the reverse: multiple-tabs -> home -> routing + * With unique outlet IDs, views are isolated and properly unmounted. + */ + it('should navigate home -> multiple-tabs -> home -> routing without stale views', () => { + // Start at home + cy.visit(`http://localhost:${port}/`); + cy.ionPageVisible('home'); + + // Navigate to multiple-tabs + cy.contains('ion-item', 'Multiple Tabs').click(); + cy.ionPageVisible('PageA'); + cy.url().should('include', '/multiple-tabs/tab1/pagea'); + + // Go back to home + cy.go('back'); + cy.ionPageVisible('home'); + + // Navigate to routing - stale views from multiple-tabs should be cleaned up + cy.contains('ion-item', 'Routing').click(); + cy.ionPageVisible('home-page'); + cy.url().should('include', '/routing/tabs/home'); + + // PageA from multiple-tabs should NOT exist in the DOM (views are unmounted when leaving route) + cy.ionPageDoesNotExist('PageA'); + }); + + /** + * Test navigating to another page and back to routing + * With unique outlet IDs, views are isolated and properly unmounted. + */ + it('should not have overlay issues when navigating between different routes', () => { + // Start at home + cy.visit(`http://localhost:${port}/`); + cy.ionPageVisible('home'); + + // Navigate to routing + cy.contains('ion-item', 'Routing').click(); + cy.ionPageVisible('home-page'); + + // Go back to home + cy.go('back'); + cy.ionPageVisible('home'); + + // Navigate to multiple-tabs + cy.contains('ion-item', 'Multiple Tabs').click(); + cy.ionPageVisible('PageA'); + + // Go back to home again + cy.go('back'); + cy.ionPageVisible('home'); + + // Navigate back to routing - no stale views should overlay + cy.contains('ion-item', 'Routing').click(); + cy.ionPageVisible('home-page'); + + // Verify PageA does not exist in the DOM (views are unmounted when leaving route) + cy.ionPageDoesNotExist('PageA'); + }); +}); diff --git a/packages/react-router/test/base/tests/e2e/specs/dynamic-routes.cy.js b/packages/react-router/test/base/tests/e2e/specs/dynamic-routes.cy.js index 76cc14ad7b4..9e2210f47a3 100644 --- a/packages/react-router/test/base/tests/e2e/specs/dynamic-routes.cy.js +++ b/packages/react-router/test/base/tests/e2e/specs/dynamic-routes.cy.js @@ -5,6 +5,11 @@ Fixes bug reported in https://github.com/ionic-team/ionic-framework/issues/21329 */ describe('Dynamic Routes', () => { + it('/dynamic-routes/home loads directly', () => { + cy.visit(`http://localhost:${port}/dynamic-routes/home`); + cy.ionPageVisible('dynamic-routes-home'); + }); + it('/dynamic-routes, when adding a dynamic route, we should be able to navigate to it', () => { cy.visit(`http://localhost:${port}/dynamic-routes`); cy.ionPageVisible('dynamic-routes-home'); diff --git a/packages/react-router/test/base/tests/e2e/specs/nested-outlets.cy.js b/packages/react-router/test/base/tests/e2e/specs/nested-outlets.cy.js index d43d2cc64d5..f00a8783b92 100644 --- a/packages/react-router/test/base/tests/e2e/specs/nested-outlets.cy.js +++ b/packages/react-router/test/base/tests/e2e/specs/nested-outlets.cy.js @@ -83,12 +83,7 @@ describe('Nested Outlets 2', () => { cy.ionPageVisible('list'); }); - it(`/nested-outlet2 > - Go to Welcome IonItem click > - Go to list from Welcome IonItem click > - Item#1 IonItem Click > - Item page should be visible -`, () => { + it('/nested-outlet2 > Go to Welcome IonItem click > Go to list from Welcome IonItem click > Item#1 IonItem Click > Item page should be visible', () => { cy.visit(`http://localhost:${port}/nested-outlet2`); cy.ionPageVisible('home'); cy.ionNav('ion-item', 'Go to Welcome'); @@ -99,13 +94,7 @@ describe('Nested Outlets 2', () => { cy.ionPageVisible('item'); }); - it(`/nested-outlet2 > - Go to list from Home IonItem click > - Item#1 IonItem Click > - Item page should be visible > - Back > - List page should be visible -`, () => { + it('/nested-outlet2 > Go to list from Home IonItem click > Item#1 IonItem Click > Item page should be visible > Back > List page should be visible', () => { cy.visit(`http://localhost:${port}/nested-outlet2`); cy.ionPageVisible('home'); cy.ionNav('ion-item', 'Go to list from Home'); @@ -116,15 +105,7 @@ describe('Nested Outlets 2', () => { cy.ionPageVisible('list'); }); - it(`/nested-outlet2 > - Go to list from Home IonItem click > - Item#1 IonItem Click > - Item page should be visible > - Back > - List page should be visible - Back > - Home page should be visible -`, () => { + it('/nested-outlet2 > Go to list from Home IonItem click > Item#1 IonItem Click > Item page should be visible > Back > List page should be visible > Back > Home page should be visible', () => { cy.visit(`http://localhost:${port}/nested-outlet2`); cy.ionPageVisible('home'); cy.ionNav('ion-item', 'Go to list from Home'); diff --git a/packages/react-router/test/base/tests/e2e/specs/nested-params.cy.js b/packages/react-router/test/base/tests/e2e/specs/nested-params.cy.js new file mode 100644 index 00000000000..a52483192fa --- /dev/null +++ b/packages/react-router/test/base/tests/e2e/specs/nested-params.cy.js @@ -0,0 +1,70 @@ +const port = 3000; + +describe('Nested Params', () => { + /* + Tests that route params are correctly passed to nested routes + when using parameterized wildcard routes (e.g., user/:userId/*). + */ + + it('/nested-params > Landing page should be visible', () => { + cy.visit(`http://localhost:${port}/nested-params`); + cy.ionPageVisible('nested-params-landing'); + }); + + it('/nested-params > Navigate to user details > Params should be available', () => { + cy.visit(`http://localhost:${port}/nested-params`); + cy.ionPageVisible('nested-params-landing'); + + cy.get('#go-to-user-42').click(); + + cy.get('[data-testid="user-layout-param"]').should('contain', 'Layout sees user: 42'); + cy.get('[data-testid="user-details-param"]').should('contain', 'Details view user: 42'); + }); + + it('/nested-params > Navigate between sibling routes > Params should be maintained', () => { + cy.visit(`http://localhost:${port}/nested-params`); + cy.ionPageVisible('nested-params-landing'); + + // Navigate to user 42 details + cy.get('#go-to-user-42').click(); + cy.get('[data-testid="user-layout-param"]').should('contain', 'Layout sees user: 42'); + cy.get('[data-testid="user-details-param"]').should('contain', 'Details view user: 42'); + + // Navigate to settings (sibling route) + cy.get('#go-to-settings').click(); + cy.get('[data-testid="user-layout-param"]').should('contain', 'Layout sees user: 42'); + cy.get('[data-testid="user-settings-param"]').should('contain', 'Settings view user: 42'); + + // Navigate back to details + cy.contains('ion-button', 'Back to Details').click(); + cy.get('[data-testid="user-layout-param"]').should('contain', 'Layout sees user: 42'); + cy.get('[data-testid="user-details-param"]').should('contain', 'Details view user: 42'); + }); + + it('/nested-params > Direct navigation to nested route > Params should be available', () => { + // Navigate directly to a nested route with params + cy.visit(`http://localhost:${port}/nested-params/user/123/settings`); + + cy.get('[data-testid="user-layout-param"]').should('contain', 'Layout sees user: 123'); + cy.get('[data-testid="user-settings-param"]').should('contain', 'Settings view user: 123'); + }); + + it('/nested-params > Different users should have different params', () => { + cy.visit(`http://localhost:${port}/nested-params`); + cy.ionPageVisible('nested-params-landing'); + + // Navigate to user 42 + cy.get('#go-to-user-42').click(); + cy.get('[data-testid="user-layout-param"]').should('contain', 'Layout sees user: 42'); + cy.get('[data-testid="user-details-param"]').should('contain', 'Details view user: 42'); + + // Go back to landing + cy.go('back'); + cy.ionPageVisible('nested-params-landing'); + + // Navigate to user 99 + cy.get('#go-to-user-99').click(); + cy.get('[data-testid="user-layout-param"]').should('contain', 'Layout sees user: 99'); + cy.get('[data-testid="user-details-param"]').should('contain', 'Details view user: 99'); + }); +}); diff --git a/packages/react-router/test/base/tests/e2e/specs/routing.cy.js b/packages/react-router/test/base/tests/e2e/specs/routing.cy.js index fd28ee573c0..b9645ee4917 100644 --- a/packages/react-router/test/base/tests/e2e/specs/routing.cy.js +++ b/packages/react-router/test/base/tests/e2e/specs/routing.cy.js @@ -143,6 +143,7 @@ describe('Routing Tests', () => { it('/ > Menu > Favorites > Menu > Tabs, should be back on Home', () => { // Tests transferring from one outlet to another and back again via menu cy.visit(`http://localhost:${port}/routing`); + cy.ionPageVisible('home-page'); cy.ionMenuClick(); cy.ionMenuNav('Favorites'); cy.ionPageVisible('favorites-page'); @@ -275,7 +276,7 @@ describe('Routing Tests', () => { cy.ionMenuClick(); cy.ionMenuNav('Home with redirect'); cy.ionPageVisible('home-page'); - cy.ionPageDoesNotExist('favorites-page'); + cy.ionPageHidden('favorites-page'); }); it('/routing/tabs/home Menu > Favorites > Menu > Home with router, Home page should be visible, and Favorites should be hidden', () => { @@ -344,6 +345,16 @@ describe('Routing Tests', () => { cy.get('div.ion-page[data-pageid=home-details-page-1] [data-testid="details-input"]').should('have.value', '1'); }); + it('should complete chained Navigate redirects from root to /routing/tabs/home', () => { + // Tests that chained Navigate redirects work correctly: + // / > click Routing link > /routing (Navigate to tabs) > /routing/tabs (Navigate to home) > /routing/tabs/home + // This was a bug where the second Navigate would be unmounted before it could trigger + cy.visit(`http://localhost:${port}/`); + cy.ionNav('ion-item', 'Routing'); + cy.ionPageVisible('home-page'); + cy.url().should('include', '/routing/tabs/home'); + }); + /* Tests to add: Test that lifecycle events fire diff --git a/packages/react-router/test/base/tests/e2e/specs/tab-history-isolation.cy.js b/packages/react-router/test/base/tests/e2e/specs/tab-history-isolation.cy.js new file mode 100644 index 00000000000..84eeeb34882 --- /dev/null +++ b/packages/react-router/test/base/tests/e2e/specs/tab-history-isolation.cy.js @@ -0,0 +1,124 @@ +const port = 3000; + +describe('Tab History Isolation', () => { + it('should NOT navigate back to previous tab when using back button after tab bar switch', () => { + cy.visit(`http://localhost:${port}/tab-history-isolation/a`); + cy.ionPageVisible('tab-a'); + + cy.ionTabClick('Tab B'); + cy.ionPageHidden('tab-a'); + cy.ionPageVisible('tab-b'); + + cy.get(`div.ion-page[data-pageid=tab-b]`) + .find('ion-back-button') + .click({ force: true }); + + cy.wait(500); + + cy.ionPageVisible('tab-b'); + cy.ionPageHidden('tab-a'); + cy.url().should('include', '/tab-history-isolation/b'); + }); + + it('should NOT allow back navigation through multiple tab switches', () => { + cy.visit(`http://localhost:${port}/tab-history-isolation/a`); + cy.ionPageVisible('tab-a'); + + cy.ionTabClick('Tab B'); + cy.ionPageHidden('tab-a'); + cy.ionPageVisible('tab-b'); + + cy.ionTabClick('Tab C'); + cy.ionPageHidden('tab-b'); + cy.ionPageVisible('tab-c'); + + cy.get(`div.ion-page[data-pageid=tab-c]`) + .find('ion-back-button') + .click({ force: true }); + + cy.wait(500); + + cy.ionPageVisible('tab-c'); + cy.url().should('include', '/tab-history-isolation/c'); + }); + + it('should navigate back within the same tab when using back button', () => { + cy.visit(`http://localhost:${port}/tab-history-isolation/a`); + cy.ionPageVisible('tab-a'); + + cy.get('#go-to-a-details').click(); + cy.ionPageHidden('tab-a'); + cy.ionPageVisible('tab-a-details'); + + cy.ionBackClick('tab-a-details'); + cy.ionPageDoesNotExist('tab-a-details'); + cy.ionPageVisible('tab-a'); + + cy.url().should('include', '/tab-history-isolation/a'); + cy.url().should('not.include', '/details'); + }); + + it('should only navigate back within current tab after switching tabs and navigating', () => { + cy.visit(`http://localhost:${port}/tab-history-isolation/a`); + cy.ionPageVisible('tab-a'); + + cy.ionTabClick('Tab B'); + cy.ionPageHidden('tab-a'); + cy.ionPageVisible('tab-b'); + + cy.get('#go-to-b-details').click(); + cy.ionPageHidden('tab-b'); + cy.ionPageVisible('tab-b-details'); + + cy.ionBackClick('tab-b-details'); + cy.ionPageDoesNotExist('tab-b-details'); + cy.ionPageVisible('tab-b'); + + cy.url().should('include', '/tab-history-isolation/b'); + cy.url().should('not.include', '/details'); + + cy.get(`div.ion-page[data-pageid=tab-b]`) + .find('ion-back-button') + .click({ force: true }); + + cy.wait(500); + + cy.ionPageVisible('tab-b'); + cy.url().should('include', '/tab-history-isolation/b'); + }); + + it('should preserve tab history when switching away and back', () => { + cy.visit(`http://localhost:${port}/tab-history-isolation/a`); + cy.ionPageVisible('tab-a'); + + cy.get('#go-to-a-details').click(); + cy.ionPageHidden('tab-a'); + cy.ionPageVisible('tab-a-details'); + + cy.ionTabClick('Tab B'); + cy.ionPageHidden('tab-a-details'); + cy.ionPageVisible('tab-b'); + + cy.ionTabClick('Tab A'); + cy.ionPageHidden('tab-b'); + cy.ionPageVisible('tab-a-details'); + + cy.ionBackClick('tab-a-details'); + cy.ionPageDoesNotExist('tab-a-details'); + cy.ionPageVisible('tab-a'); + }); + + it('should have no back navigation when first visiting a tab', () => { + cy.visit(`http://localhost:${port}/tab-history-isolation/a`); + cy.ionPageVisible('tab-a'); + + cy.get(`div.ion-page[data-pageid=tab-a]`) + .find('ion-back-button') + .click({ force: true }); + + cy.wait(500); + + cy.ionPageVisible('tab-a'); + cy.url().should('include', '/tab-history-isolation/a'); + }); +}); diff --git a/packages/react-router/test/base/tests/e2e/support/commands.js b/packages/react-router/test/base/tests/e2e/support/commands.js index 947a796157a..ec63d211c45 100644 --- a/packages/react-router/test/base/tests/e2e/support/commands.js +++ b/packages/react-router/test/base/tests/e2e/support/commands.js @@ -27,24 +27,24 @@ // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) Cypress.Commands.add('ionPageVisible', (pageId) => { - // cy.get(`div.ion-page[data-pageid=${pageId}]`) - // .should('exist') - // .should('not.have.class', 'ion-page-hidden') - // .should('not.have.class', 'ion-page-visible') + cy.log(`[ionPageVisible] Checking for visible page: ${pageId}`); + + // First, log all current ion-page elements for debugging + cy.get('div.ion-page').then(($pages) => { + const pageStates = []; + $pages.each((i, el) => { + const id = el.getAttribute('data-pageid') || 'unknown'; + const classes = el.className; + const ariaHidden = el.getAttribute('aria-hidden'); + pageStates.push(`${id}: classes="${classes}" aria-hidden="${ariaHidden}"`); + }); + cy.log(`[ionPageVisible] All ion-page elements: ${pageStates.join(' | ')}`); + }); cy.get(`div.ion-page[data-pageid=${pageId}]`) .should('not.have.class', 'ion-page-hidden') .should('not.have.class', 'ion-page-invisible') .should('have.length', 1); - - // cy.get(`div.ion-page[data-pageid=${pageId}]`) - // .should('not.have.class', 'ion-page') - // .should('have.length', 1) - // .not('') - // .should('have.length', 1) - - // cy.get(`div.ion-page[data-pageid=${pageId}]`).should('not.have.class', 'ion-page-visible') - // cy.get(`div.ion-page[data-pageid=${pageId}]`).should('have.attr', 'style', 'z-index: 101;') }); Cypress.Commands.add('ionPageHidden', (pageId) => { @@ -82,6 +82,7 @@ Cypress.Commands.add('ionMenuNav', (contains) => { // cy.get('ion-menu.show-menu').should('exist'); // cy.wait(1000) cy.contains('ion-item', contains).click({ force: true }); + cy.wait(250); // cy.get('div.ion-page').click(); // cy.get('ion-menu').then(menu => { // cy.wait(1000) diff --git a/packages/react-router/test/base/tests/e2e/support/index.js b/packages/react-router/test/base/tests/e2e/support/index.js index 37a498fb5bf..208452ffa62 100644 --- a/packages/react-router/test/base/tests/e2e/support/index.js +++ b/packages/react-router/test/base/tests/e2e/support/index.js @@ -18,3 +18,5 @@ import './commands'; // Alternatively you can use CommonJS syntax: // require('./commands') + +require('cypress-terminal-report/src/installLogsCollector')(); diff --git a/packages/react/src/components/IonRoute.tsx b/packages/react/src/components/IonRoute.tsx index c7dc0b1af40..3bacaac2e1c 100644 --- a/packages/react/src/components/IonRoute.tsx +++ b/packages/react/src/components/IonRoute.tsx @@ -4,9 +4,8 @@ import { NavContext } from '../contexts/NavContext'; export interface IonRouteProps { path?: string; - exact?: boolean; show?: boolean; - render: (props?: any) => JSX.Element; // TODO(FW-2959): type + element: React.ReactElement; disableIonPageManagement?: boolean; } diff --git a/packages/react/src/components/IonRouterOutlet.tsx b/packages/react/src/components/IonRouterOutlet.tsx index d7c75b13189..2fe25df3893 100644 --- a/packages/react/src/components/IonRouterOutlet.tsx +++ b/packages/react/src/components/IonRouterOutlet.tsx @@ -3,6 +3,7 @@ import React from 'react'; import { NavContext } from '../contexts/NavContext'; import OutletPageManager from '../routing/OutletPageManager'; +import { generateId } from '../utils/generateId'; import type { IonicReactProps } from './IonicReactProps'; import { IonRouterOutletInner } from './inner-proxies'; @@ -12,6 +13,7 @@ type Props = LocalJSX.IonRouterOutlet & { basePath?: string; ref?: React.Ref; ionPage?: boolean; + id?: string; }; interface InternalProps extends Props { @@ -23,14 +25,17 @@ interface InternalState {} class IonRouterOutletContainer extends React.Component { context!: React.ContextType; + private readonly outletId: string; constructor(props: InternalProps) { super(props); + this.outletId = props.id ?? `routerOutlet-${generateId('routerOutlet')}`; } render() { const StackManager = this.context.getStackManager(); const { children, forwardedRef, ...props } = this.props; + const outletId = props.id ?? this.outletId; return this.context.hasIonicRouter() ? ( props.ionPage ? ( @@ -38,8 +43,8 @@ class IonRouterOutletContainer extends React.Component ) : ( - - + + {children} diff --git a/packages/react/src/routing/LocationHistory.ts b/packages/react/src/routing/LocationHistory.ts index e99e5a88cc9..bd2d3dd24c1 100644 --- a/packages/react/src/routing/LocationHistory.ts +++ b/packages/react/src/routing/LocationHistory.ts @@ -91,7 +91,18 @@ export class LocationHistory { private _replace(routeInfo: RouteInfo) { const routeInfos = this._getRouteInfosByKey(routeInfo.tab); routeInfos && routeInfos.pop(); - this.locationHistory.pop(); + + // Get the current route that's being replaced + const currentRoute = this.locationHistory[this.locationHistory.length - 1]; + + // Only pop from global history if we're replacing in the same outlet context. + // Don't pop if we're entering a nested outlet (current route has no tab, new route has a tab) + const isEnteringNestedOutlet = currentRoute && !currentRoute.tab && !!routeInfo.tab; + + if (!isEnteringNestedOutlet) { + this.locationHistory.pop(); + } + this._add(routeInfo); } diff --git a/packages/react/src/routing/OutletPageManager.tsx b/packages/react/src/routing/OutletPageManager.tsx index 0e0d1f9ea08..e970ca67742 100644 --- a/packages/react/src/routing/OutletPageManager.tsx +++ b/packages/react/src/routing/OutletPageManager.tsx @@ -12,6 +12,7 @@ interface OutletPageManagerProps { forwardedRef?: React.ForwardedRef; routeInfo?: RouteInfo; StackManager: any; // TODO(FW-2959): type + id?: string; } export class OutletPageManager extends React.Component { @@ -83,15 +84,16 @@ export class OutletPageManager extends React.Component { } render() { - const { StackManager, children, routeInfo, ...props } = this.props; + const { StackManager, children, routeInfo, id, ...props } = this.props; return ( {(context) => { this.ionLifeCycleContext = context; return ( - + (this.ionRouterOutlet = val)} + id={id} {...props} > {children} diff --git a/packages/react/src/routing/RouteManagerContext.ts b/packages/react/src/routing/RouteManagerContext.ts index 32cfa6c50f8..ba8306304af 100644 --- a/packages/react/src/routing/RouteManagerContext.ts +++ b/packages/react/src/routing/RouteManagerContext.ts @@ -23,6 +23,11 @@ export interface RouteManagerContextState { routeInfo: RouteInfo, reRender: () => void ) => React.ReactNode[]; + /** + * Returns all view items currently registered for a given outlet id. + * Used by StackManager for out-of-scope cleanup. + */ + getViewItemsForOutlet: (outletId: string) => ViewItem[]; goBack: () => void; unMountViewItem: (viewItem: ViewItem) => void; } @@ -37,6 +42,7 @@ export const RouteManagerContext = /*@__PURE__*/ React.createContext undefined, findViewItemByRouteInfo: () => undefined, getChildrenToRender: () => undefined as any, + getViewItemsForOutlet: () => [] as any, goBack: () => undefined, unMountViewItem: () => undefined, }); diff --git a/packages/react/test/apps/react17/package.json b/packages/react/test/apps/react17/package.json index 68079579bba..f05a10f55de 100644 --- a/packages/react/test/apps/react17/package.json +++ b/packages/react/test/apps/react17/package.json @@ -2,18 +2,22 @@ "name": "test-app", "version": "0.0.1", "private": true, + "overrides": { + "@ionic/react-router": { + "react-router": "$react-router", + "react-router-dom": "$react-router-dom" + } + }, "dependencies": { "@ionic/react": "^6.6.1", "@ionic/react-router": "^6.6.1", "@types/react": "^17.0.53", "@types/react-dom": "^17.0.19", - "@types/react-router": "^5.1.20", - "@types/react-router-dom": "^5.3.3", "ionicons": "^8.0.13", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-router": "^5.3.4", - "react-router-dom": "^5.3.4", + "react-router": "^6.0.0", + "react-router-dom": "^6.0.0", "react-scripts": "^5.0.0", "typescript": "^4.1.3" }, diff --git a/packages/react/test/apps/react18/package.json b/packages/react/test/apps/react18/package.json index 65ab9e00239..1c401656216 100644 --- a/packages/react/test/apps/react18/package.json +++ b/packages/react/test/apps/react18/package.json @@ -2,14 +2,20 @@ "name": "test-app", "version": "0.0.1", "private": true, + "overrides": { + "@ionic/react-router": { + "react-router": "$react-router", + "react-router-dom": "$react-router-dom" + } + }, "dependencies": { "@ionic/react": "^7.0.0", "@ionic/react-router": "^7.0.0", "ionicons": "^8.0.13", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-router": "^5.3.4", - "react-router-dom": "^5.3.4" + "react-router": "^6.0.0", + "react-router-dom": "^6.0.0" }, "scripts": { "dev": "vite", @@ -27,9 +33,6 @@ "@testing-library/user-event": "^14.4.3", "@types/react": "^18.0.27", "@types/react-dom": "^18.0.10", - "@types/react-router": "^5.1.20", - "@types/react-router-dom": "^5.3.3", - "@vitejs/plugin-legacy": "^4.0.2", "@vitejs/plugin-react": "^4.0.1", "concurrently": "^6.3.0", "cypress": "^13.2.0", diff --git a/packages/react/test/apps/react18/vite.config.ts b/packages/react/test/apps/react18/vite.config.ts index 20e6c2a8071..a5f03b990f4 100644 --- a/packages/react/test/apps/react18/vite.config.ts +++ b/packages/react/test/apps/react18/vite.config.ts @@ -1,4 +1,3 @@ -import legacy from '@vitejs/plugin-legacy' import react from '@vitejs/plugin-react' import { defineConfig } from 'vite' @@ -6,7 +5,6 @@ import { defineConfig } from 'vite' export default defineConfig({ plugins: [ react(), - legacy() ], test: { globals: true, diff --git a/packages/react/test/apps/react19/package.json b/packages/react/test/apps/react19/package.json index 67e3bf1db83..028e792fe9d 100644 --- a/packages/react/test/apps/react19/package.json +++ b/packages/react/test/apps/react19/package.json @@ -2,14 +2,20 @@ "name": "test-app", "version": "0.0.1", "private": true, + "overrides": { + "@ionic/react-router": { + "react-router": "$react-router", + "react-router-dom": "$react-router-dom" + } + }, "dependencies": { "@ionic/react": "^8.4.0", "@ionic/react-router": "^8.4.0", "ionicons": "^8.0.13", "react": "19.0.0", "react-dom": "19.0.0", - "react-router": "^5.3.4", - "react-router-dom": "^5.3.4" + "react-router": "^6.0.0", + "react-router-dom": "^6.0.0" }, "scripts": { "dev": "vite", @@ -22,15 +28,15 @@ "e2e": "concurrently \"serve -s dist -l 3000\" \"wait-on http-get://localhost:3000 && npm run cypress\" --kill-others --success first" }, "devDependencies": { + "@testing-library/dom": "^10.0.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^16.2.0", "@testing-library/user-event": "^14.4.3", "@types/react": "19.0.10", "@types/react-dom": "19.0.4", - "@types/react-router": "^5.1.20", - "@types/react-router-dom": "^5.3.3", "@vitejs/plugin-legacy": "^4.0.2", "@vitejs/plugin-react": "^4.0.1", + "terser": "^5.16.0", "concurrently": "^6.3.0", "cypress": "^13.2.0", "eslint": "^8.35.0", diff --git a/packages/react/test/base/scripts/sync.sh b/packages/react/test/base/scripts/sync.sh index a6b441d8b5c..0626fbd8f00 100755 --- a/packages/react/test/base/scripts/sync.sh +++ b/packages/react/test/base/scripts/sync.sh @@ -15,4 +15,4 @@ npm pack ../../../ npm pack ../../../../react-router # Install Dependencies -npm install *.tgz --no-save +npm install *.tgz --no-save --legacy-peer-deps diff --git a/packages/react/test/base/src/App.tsx b/packages/react/test/base/src/App.tsx index 634af89f075..860c8c69316 100644 --- a/packages/react/test/base/src/App.tsx +++ b/packages/react/test/base/src/App.tsx @@ -1,7 +1,7 @@ import { IonApp, IonRouterOutlet, setupIonicReact } from '@ionic/react'; import { IonReactRouter } from '@ionic/react-router'; import React from 'react'; -import { Route } from 'react-router-dom'; +import { Route } from 'react-router'; /* Core CSS required for Ionic components to work properly */ import '@ionic/react/css/core.css'; @@ -45,32 +45,32 @@ const App: React.FC = () => ( - - - - + } /> + } /> + } /> + } /> } /> - + } /> } /> } /> - - - - - - - - - + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> diff --git a/packages/react/test/base/src/pages/Tabs.tsx b/packages/react/test/base/src/pages/Tabs.tsx index 2098bfcb266..89c82fd2c53 100644 --- a/packages/react/test/base/src/pages/Tabs.tsx +++ b/packages/react/test/base/src/pages/Tabs.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { IonLabel, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs, IonPage } from '@ionic/react'; -import { Route, Redirect } from 'react-router'; +import { Route, Navigate } from 'react-router'; interface TabsProps {} @@ -9,8 +9,8 @@ const Tabs: React.FC = () => { - - Tab 1} /> + } /> + Tab 1} /> window.alert('Tab was clicked')}> diff --git a/packages/react/test/base/src/pages/TabsDirectNavigation.tsx b/packages/react/test/base/src/pages/TabsDirectNavigation.tsx index 2e412e174ab..c02589ad6c6 100644 --- a/packages/react/test/base/src/pages/TabsDirectNavigation.tsx +++ b/packages/react/test/base/src/pages/TabsDirectNavigation.tsx @@ -1,7 +1,7 @@ import { IonContent, IonHeader, IonIcon, IonLabel, IonPage, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs, IonTitle, IonToolbar } from '@ionic/react'; import { homeOutline, radioOutline, libraryOutline, searchOutline } from 'ionicons/icons'; import React from 'react'; -import { Route, Redirect } from 'react-router-dom'; +import { Route, Navigate } from 'react-router'; const HomePage: React.FC = () => ( @@ -59,11 +59,11 @@ const TabsDirectNavigation: React.FC = () => { return ( - - } exact={true} /> - } exact={true} /> - } exact={true} /> - } exact={true} /> + } /> + } /> + } /> + } /> + } /> diff --git a/packages/react/test/base/src/pages/overlay-components/ModalSheetChildRoute.tsx b/packages/react/test/base/src/pages/overlay-components/ModalSheetChildRoute.tsx index e686bbd00eb..976352cb847 100644 --- a/packages/react/test/base/src/pages/overlay-components/ModalSheetChildRoute.tsx +++ b/packages/react/test/base/src/pages/overlay-components/ModalSheetChildRoute.tsx @@ -38,7 +38,7 @@ const ModalSheetChildRouteParent: React.FC = () => { - + } /> ); diff --git a/packages/react/test/base/src/pages/overlay-components/OverlayComponents.tsx b/packages/react/test/base/src/pages/overlay-components/OverlayComponents.tsx index 75bf98bb734..1381ed14763 100644 --- a/packages/react/test/base/src/pages/overlay-components/OverlayComponents.tsx +++ b/packages/react/test/base/src/pages/overlay-components/OverlayComponents.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { IonIcon, IonLabel, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs } from '@ionic/react'; -import { Route, Redirect } from 'react-router'; +import { Route, Navigate } from 'react-router'; import { addCircleOutline, alarm, @@ -27,17 +27,17 @@ const OverlayHooks: React.FC = () => { return ( - - - - - - - - - - - + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> diff --git a/packages/react/test/base/src/pages/overlay-hooks/OverlayHooks.tsx b/packages/react/test/base/src/pages/overlay-hooks/OverlayHooks.tsx index 4cc9bf88ddd..8036c0efbee 100644 --- a/packages/react/test/base/src/pages/overlay-hooks/OverlayHooks.tsx +++ b/packages/react/test/base/src/pages/overlay-hooks/OverlayHooks.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { IonIcon, IonLabel, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs } from '@ionic/react'; -import { Route, Redirect } from 'react-router'; +import { Route, Navigate } from 'react-router'; import ActionSheetHook from './ActionSheetHook'; import { addCircleOutline, @@ -24,14 +24,14 @@ const OverlayHooks: React.FC = () => { return ( - - - - - - - - + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } />