diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..d41d473 --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +# Include for running the Playwright tests in Docker +# This is switched out in CI when the Docker container isn't required +PLAYWRIGHT_BASE_URL=http://host.docker.internal:6006 + +# Anthropic API key +ANTHROPIC_API_KEY= \ No newline at end of file diff --git a/.github/workflows/playwright.yaml b/.github/workflows/playwright.yaml new file mode 100644 index 0000000..08750ae --- /dev/null +++ b/.github/workflows/playwright.yaml @@ -0,0 +1,36 @@ +name: 'Playwright Tests' +on: + push: + branches: + - main + pull_request: + branches: + - main +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + env: + PLAYWRIGHT_BASE_URL: http://localhost:6006 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Build Storybook + run: npm run build-storybook + - name: Serve Storybook and run Playwright tests + run: | + npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \ + "npx http-server storybook-static --port 6006 --silent" \ + "npx wait-on tcp:6006 && npx playwright test" + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index c6097ab..5bfdd30 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ yarn-error.log* # local env files .env*.local +.env # vercel .vercel @@ -36,3 +37,9 @@ yarn-error.log* next-env.d.ts *storybook.log + +# playwright +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/documentation/getting-started.md b/documentation/getting-started.md index 24dae23..3d295b0 100644 --- a/documentation/getting-started.md +++ b/documentation/getting-started.md @@ -29,3 +29,31 @@ npm run dev Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. Make sure that you don't have any other app already running on `3000` otherwise the site may show up on another port number. If you'd like to contribute to the project, create a branch off of `main` with a description of the feature or bug fix. + +## Running Storybook + +Components used in this project are documented in a Storybook instance. To run storybook locally, use the following command: + +`npm run storybook` + +To run automated smoke and accessibility tests over the Storybook stories, open a new terminal window. Then run `npm run test-storybook`. + +## Running Playwright tests + +The Playwright tests for this repository are based on the Storybook instance, so make sure this is running first. There are different methods of setting up your environment depending on the device you are using: + +### Linux + +Edit your `.env` file so that the `PLAYWRIGHT_BASE_URL=http://localhost:6006` + +### Windows and MacOS + +Edit your `.env` file so that the `PLAYWRIGHT_BASE_URL=http://host.docker.internal:6006` + +Run `npm run docker-playwright` to enter a docker container. This means that CI and you will have the same operating system while testing visual regression, standardising font rendering and other small differences. + +### Test commands + +You can now run tests using `npm run playwright` + +To update snapshots, run `npm run playwright -- --update-snapshots`. If you just want to update one component, use `npm run playwright -- header --update-snapshots` and only the name of the component specified will be run. diff --git a/package-lock.json b/package-lock.json index b11403b..1d3c8fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,11 @@ "name": "social-bristol", "version": "0.1.0", "dependencies": { + "@anthropic-ai/sdk": "^0.27.1", "@types/node": "20.5.6", "@types/react": "18.2.21", "@types/react-dom": "18.2.7", + "dotenv": "^16.4.5", "eslint": "8.56.0", "eslint-config-next": "14.2.3", "leaflet": "1.9.4", @@ -21,10 +23,10 @@ "react-dom": "18.2.0", "react-leaflet": "4.2.1", "sass": "1.70.0", - "stylelint-config-css-modules": "^4.4.0", "typescript": "5.3.3" }, "devDependencies": { + "@playwright/test": "1.46.0", "@storybook/addon-a11y": "8.2.7", "@storybook/addon-essentials": "8.2.7", "@storybook/addon-interactions": "8.2.7", @@ -41,9 +43,10 @@ "eslint-config-torchbox": "1.1.0", "eslint-plugin-storybook": "0.8.0", "storybook": "8.2.7", - "stylelint": "^16.8.1", - "stylelint-config-standard": "^36.0.1", - "stylelint-config-standard-scss": "^13.1.0" + "stylelint": "16.8.1", + "stylelint-config-css-modules": "4.4.0", + "stylelint-config-standard": "36.0.1", + "stylelint-config-standard-scss": "13.1.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -73,10 +76,35 @@ "node": ">=6.0.0" } }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.27.1.tgz", + "integrity": "sha512-AKFd/E8HO26+DOVPiZpEked3Pm2feA5d4gcX2FcJXr9veDkXbKO90hr2C7N2TL7mPIMwm040ldXlsIZQ416dHg==", + "license": "MIT", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + } + }, + "node_modules/@anthropic-ai/sdk/node_modules/@types/node": { + "version": "18.19.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.47.tgz", + "integrity": "sha512-1f7dB3BL/bpd9tnDJrrHb66Y+cVrhxSOTGorRNdHwYTUlTay3HuTDPKo9a/4vX9pMQkhYBcAbL4jQdNlhCFP9A==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@babel/code-frame": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, "dependencies": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" @@ -487,6 +515,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -532,6 +561,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", @@ -546,6 +576,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -557,6 +588,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -570,6 +602,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -577,12 +610,14 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, "engines": { "node": ">=0.8.0" } @@ -591,6 +626,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, "engines": { "node": ">=4" } @@ -599,6 +635,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -2287,6 +2324,7 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.1.tgz", "integrity": "sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==", + "dev": true, "funding": [ { "type": "github", @@ -2308,6 +2346,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.4.1.tgz", "integrity": "sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==", + "dev": true, "funding": [ { "type": "github", @@ -2326,6 +2365,7 @@ "version": "2.1.13", "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.13.tgz", "integrity": "sha512-XaHr+16KRU9Gf8XLi3q8kDlI18d5vzKSKCY510Vrtc9iNR0NJzbY9hhTmwhzYZj/ZwGL4VmB3TA9hJW0Um2qFA==", + "dev": true, "funding": [ { "type": "github", @@ -2348,6 +2388,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", + "dev": true, "funding": [ { "type": "github", @@ -2369,6 +2410,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", "integrity": "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==", + "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4074,6 +4116,22 @@ "node": ">=14" } }, + "node_modules/@playwright/test": { + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.46.0.tgz", + "integrity": "sha512-/QYft5VArOrGRP5pgkrfKksqsKA6CEFyGQ/gjNe6q0y4tZ1aaPfq4gIjudr1s3D+pXyrPRdsy4opKDrjBabE5w==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.46.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", @@ -5732,26 +5790,6 @@ "integrity": "sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig==", "dev": true }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { "version": "0.0.51", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", @@ -5891,6 +5929,16 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.6.tgz", "integrity": "sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==" }, + "node_modules/@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", @@ -6465,7 +6513,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, "dependencies": { "event-target-shim": "^5.0.0" }, @@ -6562,6 +6609,18 @@ "node": ">=8.9.0" } }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -6941,6 +7000,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, "engines": { "node": ">=8" } @@ -6956,8 +7016,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/available-typed-arrays": { "version": "1.0.5", @@ -7011,10 +7070,11 @@ } }, "node_modules/axios": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", - "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "dev": true, + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -8185,7 +8245,8 @@ "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true }, "node_modules/colorette": { "version": "2.0.20", @@ -8197,7 +8258,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -8490,6 +8550,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz", "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==", + "dev": true, "engines": { "node": ">=12 || >=16" } @@ -8641,6 +8702,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -8671,6 +8733,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, "bin": { "cssesc": "bin/cssesc" }, @@ -8845,7 +8908,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -9070,6 +9132,18 @@ "tslib": "^2.0.3" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -9088,10 +9162,11 @@ "dev": true }, "node_modules/elliptic": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", - "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", + "version": "6.5.7", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", + "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", "dev": true, + "license": "MIT", "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -9155,9 +9230,10 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -9176,6 +9252,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, "engines": { "node": ">=6" } @@ -9196,6 +9273,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } @@ -10002,7 +10080,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, "engines": { "node": ">=6" } @@ -10205,12 +10282,14 @@ "node_modules/fast-uri": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==" + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, "engines": { "node": ">= 4.9.1" } @@ -10518,7 +10597,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -10528,6 +10606,25 @@ "node": ">= 6" } }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "license": "MIT" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "license": "MIT", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -10913,7 +11010,8 @@ "node_modules/globjoin": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==" + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true }, "node_modules/gopd": { "version": "1.0.1", @@ -11206,6 +11304,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, "engines": { "node": ">=8" }, @@ -11304,6 +11403,15 @@ "node": ">=10.17.0" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -11443,7 +11551,8 @@ "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true }, "node_modules/internal-slot": { "version": "1.0.5", @@ -11511,7 +11620,8 @@ "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "node_modules/is-async-function": { "version": "2.0.0", @@ -11739,6 +11849,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -13025,12 +13136,14 @@ "node_modules/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==" + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -13104,6 +13217,7 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, "dependencies": { "json-buffer": "3.0.1" } @@ -13112,6 +13226,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -13137,7 +13252,8 @@ "node_modules/known-css-properties": { "version": "0.34.0", "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", - "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==" + "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", + "dev": true }, "node_modules/language-subtag-registry": { "version": "0.3.22", @@ -13181,7 +13297,8 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true }, "node_modules/loader-runner": { "version": "4.3.0", @@ -13240,7 +13357,8 @@ "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true }, "node_modules/log-symbols": { "version": "4.1.0", @@ -13439,6 +13557,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -13458,7 +13577,8 @@ "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true }, "node_modules/media-typer": { "version": "0.3.0", @@ -13494,6 +13614,7 @@ "version": "13.2.0", "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true, "engines": { "node": ">=18" }, @@ -13531,9 +13652,10 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -13577,7 +13699,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -13586,7 +13707,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -13835,6 +13955,45 @@ "node": ">= 0.10.5" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-fetch-native": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz", @@ -14668,6 +14827,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -14925,7 +15085,7 @@ "version": "1.46.0", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.0.tgz", "integrity": "sha512-XYJ5WvfefWONh1uPAUAi0H2xXV5S3vrtcnXe6uAOgdGi3aSpqOSXX08IAjXW34xitfuOJsvXU5anXZxPSEQiJw==", - "dev": true, + "devOptional": true, "dependencies": { "playwright-core": "1.46.0" }, @@ -14943,7 +15103,7 @@ "version": "1.46.0", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.0.tgz", "integrity": "sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==", - "dev": true, + "devOptional": true, "bin": { "playwright-core": "cli.js" }, @@ -15077,7 +15237,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "devOptional": true + "dev": true }, "node_modules/postcss-modules-extract-imports": { "version": "3.1.0", @@ -15141,12 +15301,14 @@ "node_modules/postcss-resolve-nested-selector": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.4.tgz", - "integrity": "sha512-R6vHqZWgVnTAPq0C+xjyHfEZqfIYboCBVSy24MjxEDm+tIh1BU4O6o7DP7AA7kHzf136d+Qc5duI4tlpHjixDw==" + "integrity": "sha512-R6vHqZWgVnTAPq0C+xjyHfEZqfIYboCBVSy24MjxEDm+tIh1BU4O6o7DP7AA7kHzf136d+Qc5duI4tlpHjixDw==", + "dev": true }, "node_modules/postcss-safe-parser": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz", "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==", + "dev": true, "funding": [ { "type": "opencollective", @@ -15198,6 +15360,7 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", + "dev": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -15209,7 +15372,8 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -16113,6 +16277,7 @@ "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, "engines": { "node": ">=0.10.0" } @@ -16785,6 +16950,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -17354,6 +17520,7 @@ "version": "16.8.1", "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.8.1.tgz", "integrity": "sha512-O8aDyfdODSDNz/B3gW2HQ+8kv8pfhSu7ZR7xskQ93+vI6FhKKGUJMQ03Ydu+w3OvXXE0/u4hWU4hCPNOyld+OA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -17416,6 +17583,7 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/stylelint-config-css-modules/-/stylelint-config-css-modules-4.4.0.tgz", "integrity": "sha512-J93MtxPjRzs/TjwbJ5y9SQy4iIqULXwL1CF1yx2tQCJfS/VZUcDAmoGOwqlLbhHXSQtZO5XQiA75NVWUR3KDCQ==", + "dev": true, "optionalDependencies": { "stylelint-scss": "^6.0.0" }, @@ -17519,7 +17687,7 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-6.5.0.tgz", "integrity": "sha512-yOnYlr71wrTPT3rYyUurgTj6Rw7JUtzsZQsiPEjvs+k/yqoYHdweqpw6XN/ARpxjAuvJpddoMUvV8aAIpvUwTg==", - "devOptional": true, + "dev": true, "dependencies": { "css-tree": "2.3.1", "is-plain-object": "5.0.0", @@ -17539,12 +17707,14 @@ "node_modules/stylelint/node_modules/balanced-match": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==" + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true }, "node_modules/stylelint/node_modules/cosmiconfig": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -17569,12 +17739,14 @@ "node_modules/stylelint/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==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/stylelint/node_modules/file-entry-cache": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz", "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==", + "dev": true, "dependencies": { "flat-cache": "^5.0.0" }, @@ -17586,6 +17758,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz", "integrity": "sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==", + "dev": true, "dependencies": { "flatted": "^3.3.1", "keyv": "^4.5.4" @@ -17598,6 +17771,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, "dependencies": { "global-prefix": "^3.0.0" }, @@ -17609,6 +17783,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -17622,6 +17797,7 @@ "version": "8.4.41", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "dev": true, "funding": [ { "type": "opencollective", @@ -17649,6 +17825,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, "engines": { "node": ">=8" } @@ -17657,6 +17834,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -17670,6 +17848,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -17681,6 +17860,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -17695,6 +17875,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, "engines": { "node": ">=12" }, @@ -17706,6 +17887,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -17717,6 +17899,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -17740,6 +17923,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -17762,12 +17946,14 @@ "node_modules/svg-tags": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==" + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true }, "node_modules/table": { "version": "6.8.2", "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dev": true, "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -17783,6 +17969,7 @@ "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, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -17797,17 +17984,20 @@ "node_modules/table/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==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/table/node_modules/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==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true }, "node_modules/table/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -18093,6 +18283,12 @@ "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -18372,8 +18568,7 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", @@ -18602,7 +18797,8 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true }, "node_modules/utila": { "version": "0.4.0", @@ -18834,13 +19030,28 @@ "defaults": "^1.0.3" } }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, "node_modules/webpack": { - "version": "5.93.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", - "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, + "license": "MIT", "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", @@ -18849,7 +19060,7 @@ "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -18981,6 +19192,16 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -19334,10 +19555,35 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, + "@anthropic-ai/sdk": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.27.1.tgz", + "integrity": "sha512-AKFd/E8HO26+DOVPiZpEked3Pm2feA5d4gcX2FcJXr9veDkXbKO90hr2C7N2TL7mPIMwm040ldXlsIZQ416dHg==", + "requires": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + }, + "dependencies": { + "@types/node": { + "version": "18.19.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.47.tgz", + "integrity": "sha512-1f7dB3BL/bpd9tnDJrrHb66Y+cVrhxSOTGorRNdHwYTUlTay3HuTDPKo9a/4vX9pMQkhYBcAbL4jQdNlhCFP9A==", + "requires": { + "undici-types": "~5.26.4" + } + } + } + }, "@babel/code-frame": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, "requires": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" @@ -19646,7 +19892,8 @@ "@babel/helper-validator-identifier": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==" + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true }, "@babel/helper-validator-option": { "version": "7.24.8", @@ -19680,6 +19927,7 @@ "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", @@ -19691,6 +19939,7 @@ "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" } @@ -19699,6 +19948,7 @@ "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", @@ -19709,6 +19959,7 @@ "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" } @@ -19716,22 +19967,26 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "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==" + "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==" + "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" } @@ -20884,29 +21139,34 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.1.tgz", "integrity": "sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==", + "dev": true, "requires": {} }, "@csstools/css-tokenizer": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.4.1.tgz", - "integrity": "sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==" + "integrity": "sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==", + "dev": true }, "@csstools/media-query-list-parser": { "version": "2.1.13", "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.13.tgz", "integrity": "sha512-XaHr+16KRU9Gf8XLi3q8kDlI18d5vzKSKCY510Vrtc9iNR0NJzbY9hhTmwhzYZj/ZwGL4VmB3TA9hJW0Um2qFA==", + "dev": true, "requires": {} }, "@csstools/selector-specificity": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", + "dev": true, "requires": {} }, "@dual-bundle/import-meta-resolve": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==" + "integrity": "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==", + "dev": true }, "@emnapi/runtime": { "version": "1.2.0", @@ -21854,6 +22114,15 @@ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "optional": true }, + "@playwright/test": { + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.46.0.tgz", + "integrity": "sha512-/QYft5VArOrGRP5pgkrfKksqsKA6CEFyGQ/gjNe6q0y4tZ1aaPfq4gIjudr1s3D+pXyrPRdsy4opKDrjBabE5w==", + "devOptional": true, + "requires": { + "playwright": "1.46.0" + } + }, "@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", @@ -22950,26 +23219,6 @@ "integrity": "sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig==", "dev": true }, - "@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "@types/estree": { "version": "0.0.51", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", @@ -23109,6 +23358,15 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.6.tgz", "integrity": "sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==" }, + "@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "requires": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, "@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", @@ -23579,7 +23837,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, "requires": { "event-target-shim": "^5.0.0" } @@ -23647,6 +23904,14 @@ } } }, + "agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "requires": { + "humanize-ms": "^1.2.1" + } + }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -23929,7 +24194,8 @@ "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true }, "asynciterator.prototype": { "version": "1.0.0", @@ -23942,8 +24208,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "available-typed-arrays": { "version": "1.0.5", @@ -23979,9 +24244,9 @@ } }, "axios": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", - "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "dev": true, "requires": { "follow-redirects": "^1.15.6", @@ -24877,7 +25142,8 @@ "colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true }, "colorette": { "version": "2.0.20", @@ -24889,7 +25155,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -25128,7 +25393,8 @@ "css-functions-list": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz", - "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==" + "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==", + "dev": true }, "css-loader": { "version": "6.11.0", @@ -25221,6 +25487,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, "requires": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -25241,7 +25508,8 @@ "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true }, "csstype": { "version": "3.1.2", @@ -25364,8 +25632,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "depd": { "version": "2.0.0", @@ -25548,6 +25815,11 @@ "tslib": "^2.0.3" } }, + "dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==" + }, "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -25566,9 +25838,9 @@ "dev": true }, "elliptic": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", - "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", + "version": "6.5.7", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", + "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", "dev": true, "requires": { "bn.js": "^4.11.9", @@ -25623,9 +25895,9 @@ } }, "enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -25640,7 +25912,8 @@ "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true }, "envinfo": { "version": "7.13.0", @@ -25652,6 +25925,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -26261,8 +26535,7 @@ "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, "events": { "version": "3.3.0", @@ -26441,12 +26714,14 @@ "fast-uri": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==" + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true }, "fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==" + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true }, "fastq": { "version": "1.15.0", @@ -26677,13 +26952,26 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, + "form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" + }, + "formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "requires": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -26950,7 +27238,8 @@ "globjoin": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==" + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true }, "gopd": { "version": "1.0.1", @@ -27158,7 +27447,8 @@ "html-tags": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==" + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true }, "html-webpack-plugin": { "version": "5.6.0", @@ -27225,6 +27515,14 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "requires": { + "ms": "^2.0.0" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -27312,7 +27610,8 @@ "ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true }, "internal-slot": { "version": "1.0.5", @@ -27359,7 +27658,8 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "is-async-function": { "version": "2.0.0", @@ -27502,7 +27802,8 @@ "is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true }, "is-regex": { "version": "1.1.4", @@ -28469,12 +28770,14 @@ "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==" + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "json-schema-traverse": { "version": "0.4.1", @@ -28537,6 +28840,7 @@ "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" } @@ -28544,7 +28848,8 @@ "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true }, "kleur": { "version": "3.0.3", @@ -28561,7 +28866,8 @@ "known-css-properties": { "version": "0.34.0", "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", - "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==" + "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", + "dev": true }, "language-subtag-registry": { "version": "0.3.22", @@ -28599,7 +28905,8 @@ "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true }, "loader-runner": { "version": "4.3.0", @@ -28646,7 +28953,8 @@ "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true }, "log-symbols": { "version": "4.1.0", @@ -28797,7 +29105,8 @@ "mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", - "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==" + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true }, "md5.js": { "version": "1.3.5", @@ -28813,7 +29122,8 @@ "mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true }, "media-typer": { "version": "0.3.0", @@ -28842,7 +29152,8 @@ "meow": { "version": "13.2.0", "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", - "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==" + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true }, "merge-descriptors": { "version": "1.0.1", @@ -28868,9 +29179,9 @@ "dev": true }, "micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "requires": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -28903,14 +29214,12 @@ "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "requires": { "mime-db": "1.52.0" } @@ -29084,6 +29393,19 @@ "minimatch": "^3.0.2" } }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, "node-fetch-native": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz", @@ -29707,6 +30029,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -29899,7 +30222,7 @@ "version": "1.46.0", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.0.tgz", "integrity": "sha512-XYJ5WvfefWONh1uPAUAi0H2xXV5S3vrtcnXe6uAOgdGi3aSpqOSXX08IAjXW34xitfuOJsvXU5anXZxPSEQiJw==", - "dev": true, + "devOptional": true, "requires": { "fsevents": "2.3.2", "playwright-core": "1.46.0" @@ -29918,7 +30241,7 @@ "version": "1.46.0", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.0.tgz", "integrity": "sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==", - "dev": true + "devOptional": true }, "pnp-webpack-plugin": { "version": "1.7.0", @@ -29977,7 +30300,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "devOptional": true + "dev": true }, "postcss-modules-extract-imports": { "version": "3.1.0", @@ -30018,12 +30341,14 @@ "postcss-resolve-nested-selector": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.4.tgz", - "integrity": "sha512-R6vHqZWgVnTAPq0C+xjyHfEZqfIYboCBVSy24MjxEDm+tIh1BU4O6o7DP7AA7kHzf136d+Qc5duI4tlpHjixDw==" + "integrity": "sha512-R6vHqZWgVnTAPq0C+xjyHfEZqfIYboCBVSy24MjxEDm+tIh1BU4O6o7DP7AA7kHzf136d+Qc5duI4tlpHjixDw==", + "dev": true }, "postcss-safe-parser": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz", "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==", + "dev": true, "requires": {} }, "postcss-scss": { @@ -30037,6 +30362,7 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", + "dev": true, "requires": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -30045,7 +30371,8 @@ "postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true }, "prelude-ls": { "version": "1.2.1", @@ -30701,7 +31028,8 @@ "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==" + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true }, "require-main-filename": { "version": "2.0.0", @@ -31193,6 +31521,7 @@ "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", @@ -31616,6 +31945,7 @@ "version": "16.8.1", "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.8.1.tgz", "integrity": "sha512-O8aDyfdODSDNz/B3gW2HQ+8kv8pfhSu7ZR7xskQ93+vI6FhKKGUJMQ03Ydu+w3OvXXE0/u4hWU4hCPNOyld+OA==", + "dev": true, "requires": { "@csstools/css-parser-algorithms": "^2.7.1", "@csstools/css-tokenizer": "^2.4.1", @@ -31661,12 +31991,14 @@ "balanced-match": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==" + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true }, "cosmiconfig": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, "requires": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -31677,12 +32009,14 @@ "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==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "file-entry-cache": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz", "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==", + "dev": true, "requires": { "flat-cache": "^5.0.0" } @@ -31691,6 +32025,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz", "integrity": "sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==", + "dev": true, "requires": { "flatted": "^3.3.1", "keyv": "^4.5.4" @@ -31700,6 +32035,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, "requires": { "global-prefix": "^3.0.0" } @@ -31708,6 +32044,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, "requires": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -31718,6 +32055,7 @@ "version": "8.4.41", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "dev": true, "requires": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", @@ -31727,12 +32065,14 @@ "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "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", @@ -31743,6 +32083,7 @@ "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" } @@ -31753,6 +32094,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "requires": { "ansi-regex": "^6.0.1" }, @@ -31760,7 +32102,8 @@ "ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true } } }, @@ -31768,6 +32111,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, "requires": { "isexe": "^2.0.0" } @@ -31776,6 +32120,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, "requires": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -31787,6 +32132,7 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/stylelint-config-css-modules/-/stylelint-config-css-modules-4.4.0.tgz", "integrity": "sha512-J93MtxPjRzs/TjwbJ5y9SQy4iIqULXwL1CF1yx2tQCJfS/VZUcDAmoGOwqlLbhHXSQtZO5XQiA75NVWUR3KDCQ==", + "dev": true, "requires": { "stylelint-scss": "^6.0.0" } @@ -31832,7 +32178,7 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-6.5.0.tgz", "integrity": "sha512-yOnYlr71wrTPT3rYyUurgTj6Rw7JUtzsZQsiPEjvs+k/yqoYHdweqpw6XN/ARpxjAuvJpddoMUvV8aAIpvUwTg==", - "devOptional": true, + "dev": true, "requires": { "css-tree": "2.3.1", "is-plain-object": "5.0.0", @@ -31855,6 +32201,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, "requires": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -31868,12 +32215,14 @@ "svg-tags": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==" + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true }, "table": { "version": "6.8.2", "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dev": true, "requires": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", @@ -31886,6 +32235,7 @@ "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, "requires": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -31896,17 +32246,20 @@ "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==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "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==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "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", @@ -32112,6 +32465,11 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -32315,8 +32673,7 @@ "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", @@ -32476,7 +32833,8 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true }, "utila": { "version": "0.4.0", @@ -32655,13 +33013,22 @@ "defaults": "^1.0.3" } }, + "web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, "webpack": { - "version": "5.93.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", - "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, "requires": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", @@ -32670,7 +33037,7 @@ "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -32758,6 +33125,15 @@ "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", "dev": true }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 636b7a7..c5ad6e1 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,19 @@ "format": "prettier --write '**/?(.)*.{md,css,scss,js,ts,tsx,json,yaml,yml}'", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", - "test-storybook": "test-storybook" + "test-storybook": "test-storybook", + "docker-playwright": "docker run --rm -p 9323:9323 -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.46.0-jammy /bin/bash -c 'npm i; /bin/bash'", + "playwright": "npx playwright test", + "new-component": "node scripts/new-component.js", + "react-to-storybook": "node scripts/react-to-storybook.mjs", + "generate-visual-tests": "node scripts/generate-visual-tests.mjs" }, "dependencies": { + "@anthropic-ai/sdk": "^0.27.1", "@types/node": "20.5.6", "@types/react": "18.2.21", "@types/react-dom": "18.2.7", + "dotenv": "^16.4.5", "eslint": "8.56.0", "eslint-config-next": "14.2.3", "leaflet": "1.9.4", @@ -29,6 +36,7 @@ "typescript": "5.3.3" }, "devDependencies": { + "@playwright/test": "1.46.0", "@storybook/addon-a11y": "8.2.7", "@storybook/addon-essentials": "8.2.7", "@storybook/addon-interactions": "8.2.7", @@ -46,8 +54,8 @@ "eslint-plugin-storybook": "0.8.0", "storybook": "8.2.7", "stylelint": "16.8.1", + "stylelint-config-css-modules": "4.4.0", "stylelint-config-standard": "36.0.1", - "stylelint-config-standard-scss": "13.1.0", - "stylelint-config-css-modules": "4.4.0" + "stylelint-config-standard-scss": "13.1.0" } } diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..5fa3666 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,44 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, devices } from '@playwright/test'; +import dotenv from 'dotenv'; +import path from 'path'; + +dotenv.config({ path: path.resolve(__dirname, '.env') }); + +export default defineConfig({ + testDir: './src', + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + reporter: 'html', + use: { + baseURL: process.env.PLAYWRIGHT_BASE_URL, + trace: 'on-first-retry', + }, + projects: [ + { + name: 'desktop-chrome', + use: { ...devices['Desktop Chrome'] }, + }, + { + name: 'desktop-firefox', + use: { ...devices['Desktop Firefox'] }, + }, + { + name: 'desktop-safari', + use: { ...devices['Desktop Safari'] }, + }, + { + name: 'mobile-chrome', + use: { ...devices['Pixel 5'] }, + }, + { + name: 'mobile-safari', + use: { ...devices['iPhone 12'] }, + }, + ], +}); diff --git a/scripts/new-component.js b/scripts/new-component.js new file mode 100644 index 0000000..3c387f8 --- /dev/null +++ b/scripts/new-component.js @@ -0,0 +1,137 @@ +/* eslint-disable no-console */ +const fs = require('fs'); +const path = require('path'); +const readline = require('readline'); +const { toCamelCase } = require('./utils.mjs'); + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +rl.question('\x1b[1mEnter a component name:\x1b[0m ', (componentName) => { + const camelComponentName = + toCamelCase(componentName)[0].toUpperCase() + + toCamelCase(componentName).slice(1); + + const componentPath = path.join( + __dirname, + '..', + 'src', + 'components', + camelComponentName, + ); + + if (fs.existsSync(componentPath)) { + console.error(`Component "${camelComponentName}" already exists.`); + rl.close(); + process.exit(1); + } + + const INDEX_TEMPLATE = `import { ${camelComponentName} } from './${camelComponentName}'; + +export default ${camelComponentName}; +`; + + const SCSS_TEMPLATE = `.container { + +} +`; + + const REACT_COMPONENT_TEMPLATE = `import React from 'react'; +import styles from './${camelComponentName}.module.scss'; + +export const ${camelComponentName} = () => { + return ( +
+ +
+ ); +}; +`; + + const STORYBOOK_TEMPLATE = `import type { Meta, StoryObj } from '@storybook/react'; +import { ${camelComponentName} } from './${camelComponentName}'; + +const meta = { + title: 'Components/${camelComponentName}', + component: ${camelComponentName}, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + argTypes: { + text: { control: 'text' }, + }, + args: { + text: 'Hello world', + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; +`; + + const VISUAL_TEST_TEMPLATE = `import { test, expect } from '@playwright/test'; + +test('visual regression', async ({ page }) => { + await page.goto( + '/iframe.html?args=&id=components-${componentName}--default', + ); + + await expect(page.locator('#storybook-root')).toHaveScreenshot( + '${componentName}.png', + ); +}); + +`; + + const files = [ + { + newPath: `${camelComponentName}.module.scss`, + content: SCSS_TEMPLATE, + }, + { + newPath: `${camelComponentName}.tsx`, + content: REACT_COMPONENT_TEMPLATE, + }, + { + newPath: `${camelComponentName}.stories.ts`, + content: STORYBOOK_TEMPLATE, + }, + { + newPath: `tests/${camelComponentName}.visual.spec.ts`, + content: VISUAL_TEST_TEMPLATE, + }, + { + newPath: `index.ts`, + content: INDEX_TEMPLATE, + }, + ]; + + try { + fs.mkdirSync(componentPath, { recursive: true }); + + files.forEach(({ newPath }) => { + const dirPath = newPath.split('/').slice(0, -1).join('/'); // Extract directory path + fs.mkdirSync(path.join(componentPath, dirPath), { + recursive: true, + }); + }); + + files.forEach(({ newPath, content }) => { + fs.writeFileSync(path.join(componentPath, newPath), content); + console.log(`Created file: \x1b[4m${newPath}\x1b[0m`); + }); + console.log( + `\n\x1b[32mComponent "${camelComponentName}" created successfully!\x1b[0m\n`, + ); + } catch (error) { + console.error('Error creating component:', error); + } + + rl.close(); +}); diff --git a/scripts/react-to-storybook.mjs b/scripts/react-to-storybook.mjs new file mode 100644 index 0000000..88c153c --- /dev/null +++ b/scripts/react-to-storybook.mjs @@ -0,0 +1,357 @@ +/* eslint-disable no-console */ +import Anthropic from '@anthropic-ai/sdk'; +import fs from 'fs'; +import readline from 'readline'; +import path from 'path'; +import { config } from 'dotenv'; +import { toCamelCase, readFile, calculateUsageCost } from './utils.mjs'; + +config(); + +// Define the model constant here +// Options: 'Claude 3 Haiku', 'Claude 3.5 Sonnet', 'Claude 3 Opus' +const ANTHROPIC_MODEL = 'Claude 3 Haiku'; + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +const anthropic = new Anthropic({}); + +const exampleDocumentation= ` +--- REACT COMPONENT --- +import React from 'react'; +import Link from 'next/link'; +import { ClockIcon } from '@/components/Icons/ClockIcon'; +import { WalletIcon } from '@/components/Icons/WalletIcon'; +import { LocationIcon } from '@/components/Icons/LocationIcon'; +import { ReceiptIcon } from '@/components/Icons/ReceiptIcon'; +import { ExternalIcon } from '@/components/Icons/ExternalIcon'; +import { FemaleIcon } from '@/components/Icons/FemaleIcon'; +import { MaleIcon } from '@/components/Icons/MaleIcon'; +import { getAMPMTimeFromDateString } from '@/utils/utils'; +import { Event } from '@/types/Event'; +import styles from './EventCard.module.scss'; + +const EventCard = ({ + cost, + time, + location, + locationURL, + booking, + url, + gender, +}: Event) => { + return ( +
+ {gender && ( +
+ {gender === 'Women' && ( + + )} + {gender === 'Men' && ( + + )} +

Open to {gender.toLowerCase()} only.

+
+ )} + {time && ( +
+ +

+ {time.frequency === 'Weekly' ? ( + <> + Every {time.weekday} + + ) : ( + {time.frequency} + )}{' '} + from{' '} + {getAMPMTimeFromDateString(time.start)}{' '} + to{' '} + {getAMPMTimeFromDateString(time.end)} +

+
+ )} + {cost && ( +
+ +

+ Costs £{cost.sessionPrice.toFixed(2)}{' '} + per session +

+
+ )} + {booking && booking.required && ( +
+ +

+ {booking.required === 'Advised' ? ( + Advance booking advised + ) : ( + Advance booking required + )} +

+
+ )} +
+ +
+ {location && ( +

+ Meets at{' '} + + {location.address} + + +

+ )} + {locationURL && ( +

+ This event's location changes,{' '} + + click here for the latest details + + +

+ )} +
+
+
+ + View group's website + +
+
+ ); +}; + +export default EventCard; + +--- STORYBOOK STORY --- +import type { Meta, StoryObj } from '@storybook/react'; +import { MOCK_EVENTS } from '@/stories/mocks'; +import EventCard from './EventCard'; + +const meta = { + title: 'Components/Cards/EventCard', + component: EventCard, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + argTypes: { + cost: { control: 'object' }, + time: { control: 'object' }, + location: { control: 'object' }, + locationURL: { control: 'text' }, + booking: { control: 'object' }, + url: { control: 'text' }, + }, + args: {}, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { ...MOCK_EVENTS[0] }, +}; + +--- REACT COMPONENT --- +'use client'; + +import React from 'react'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'; +import Link from 'next/link'; +import { rubik } from '@/pages/_app'; +import { ExternalIcon } from '../Icons/ExternalIcon'; +import styles from './Map.module.scss'; + +type MapProps = { + groups: any[]; + selectedWeekday?: string; +}; + +const Map = ({ groups, selectedWeekday }: MapProps) => { + const events = []; + + for (let i = 0; i < groups.length; i += 1) { + if (groups[i].events) { + for (let j = 0; j < groups[i].events.length; j += 1) { + let event; + + event = groups[i].events[j]; + event.slug = groups[i].slug; + event.name = groups[i].name; + + if (groups[i].events[j].location) { + if ( + selectedWeekday && + selectedWeekday !== 'All' && + groups[i].events[j].time && + groups[i].events[j].time.weekday !== selectedWeekday + ) { + // eslint-disable-next-line no-continue + continue; + } + events.push(event); + } + } + } + } + + return ( +
+ + + {events.map((event, index) => ( + + +

+ + {event.name} + +

+

+ {event.location.address} +

+ + View group's website + +
+
+ ))} +
+
+ ); +}; + +export default Map; + +--- STORYBOOK STORY --- +import type { Meta, StoryObj } from '@storybook/react'; +import { MOCK_GROUPS } from '@/stories/mocks'; +import Map from './Map'; + +const meta = { + title: 'Components/Map', + component: Map, + parameters: { + layout: 'padded', + }, + tags: ['autodocs'], + argTypes: { + groups: { control: 'object' }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + groups: MOCK_GROUPS, + }, +}; + +`; + +const baseComponentsDirectoryName = 'src/components'; + +rl.question('\x1b[1mEnter a component name:\x1b[0m ', async (componentName) => { + + const camelCaseComponentName = toCamelCase(componentName); + + const outputFilePath = `src/components/${camelCaseComponentName}/claude.${camelCaseComponentName}.stories.ts`; + + const inputFilePath = path.join( + baseComponentsDirectoryName, + camelCaseComponentName, + `/${camelCaseComponentName}.tsx`, + ); + + const inputMocksFilePath = `src/stories/mocks.ts`; + + const reactComponentCode = readFile(inputFilePath); + const mocksCode = readFile(inputMocksFilePath); + console.log( + `\x1b[3mConverting React component to Storybook documentation using ${ANTHROPIC_MODEL}...\x1b[0m`, + ); + + let model; + switch (ANTHROPIC_MODEL) { + case 'Claude 3.5 Sonnet': + model = 'claude-3-5-sonnet-20240620'; + break; + case 'Claude 3 Opus': + model = 'claude-3-opus-20240229'; + break; + case 'Claude 3 Haiku': + default: + model = 'claude-3-haiku-20240307'; + } + + // eslint-disable-next-line no-await-in-loop + const msg = await anthropic.messages.create({ + model: model, + system: `Here are some examples of Storybook documentation of React components. + ${exampleDocumentation} + Here are some mock constants for the Storybook stories, as found in @stories/mocks: + + ${mocksCode} + + Please write the Storybook story for the following React component. Do not include any other commentary or backticks, respond only with the converted code. If you'd like to add content to the mocks file, please write this before the converted code.`, + max_tokens: 4096, + messages: [{ role: 'user', content: reactComponentCode }], + }); + + fs.writeFile(outputFilePath, msg.content[0].text, (err) => { + if (err) { + console.error('An error occurred while creating the file:', err); + } else { + console.log(`\x1b[1m\x1b[32mFile created successfully.\x1b[0m`); + } + }); + + calculateUsageCost(msg.usage, ANTHROPIC_MODEL); + + rl.close(); +}); + diff --git a/scripts/utils.mjs b/scripts/utils.mjs new file mode 100644 index 0000000..a605489 --- /dev/null +++ b/scripts/utils.mjs @@ -0,0 +1,75 @@ +import fs from 'fs'; + +/** + * Converts a string from kebab-case to camelCase. + * + * @param {string} str - The string to convert. + * @returns {string} The converted string in camelCase. + */ +export function toCamelCase(str) { + return str.replace(/-(.)/g, (_, group1) => group1.toUpperCase()); +} + +/** + * Reads the content of a file. + * + * @param {string} filePath - The path to the file to read. + * @returns {string} The content of the file or an empty string if an error occurs. + */ +export const readFile = (filePath) => { + try { + return fs.readFileSync(filePath, 'utf8'); + } catch (err) { + console.error(`Error reading file ${filePath}: ${err}`); + return ''; + } +}; + +/** + * Calculates and logs the usage cost based on input and output tokens. + * + * @param {Object} usage - The usage object containing input_tokens and output_tokens. + * @param {string} model - The model to calculate the cost for. + */ +export function calculateUsageCost(usage, model) { + let inputCostPerMillion, outputCostPerMillion; + switch (model) { + case 'Claude 3.5 Sonnet': + inputCostPerMillion = 3.75; + outputCostPerMillion = 3; + break; + case 'Claude 3 Opus': + inputCostPerMillion = 18.75; + outputCostPerMillion = 15; + break; + case 'Claude 3 Haiku': + inputCostPerMillion = 0.30; + outputCostPerMillion = 0.25; + break; + default: + console.error(`Model ${model} is not supported.`); + return; + } + + const inputTokens = usage.input_tokens; + const outputTokens = usage.output_tokens; + + const inputCost = (inputTokens / 1000000) * inputCostPerMillion; + const outputCost = (outputTokens / 1000000) * outputCostPerMillion; + + const totalCost = inputCost + outputCost; + + console.log( + `\n\x1b[4m${inputTokens}\x1b[0m input tokens, approx \x1b[1m$${inputCost.toFixed( + 4, + )}\x1b[0m`, + ); + console.log( + `\x1b[4m${outputTokens}\x1b[0m output tokens, approx \x1b[1m$${outputCost.toFixed( + 4, + )}\x1b[0m`, + ); + console.log( + `Total cost: approx \x1b[1m\x1b[36m$${totalCost.toFixed(4)}\x1b[0m\n`, + ); +} \ No newline at end of file diff --git a/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts new file mode 100644 index 0000000..3cc7dbd --- /dev/null +++ b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts @@ -0,0 +1,11 @@ +import { test, expect } from '@playwright/test'; + +test('visual regression', async ({ page }) => { + await page.goto( + '/iframe.html?args=&id=components-cards-adhoccard--default', + ); + + await expect(page.locator('#storybook-root')).toHaveScreenshot( + 'AdHocCard.png', + ); +}); diff --git a/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-desktop-chrome-linux.png b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-desktop-chrome-linux.png new file mode 100644 index 0000000..f63c835 Binary files /dev/null and b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-desktop-chrome-linux.png differ diff --git a/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-desktop-firefox-linux.png b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-desktop-firefox-linux.png new file mode 100644 index 0000000..031eec0 Binary files /dev/null and b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-desktop-firefox-linux.png differ diff --git a/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-desktop-safari-linux.png b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-desktop-safari-linux.png new file mode 100644 index 0000000..b5d9be8 Binary files /dev/null and b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-desktop-safari-linux.png differ diff --git a/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-mobile-chrome-linux.png b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-mobile-chrome-linux.png new file mode 100644 index 0000000..d2731a6 Binary files /dev/null and b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-mobile-chrome-linux.png differ diff --git a/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-mobile-safari-linux.png b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-mobile-safari-linux.png new file mode 100644 index 0000000..dba58dc Binary files /dev/null and b/src/components/AdHocCard/tests/AdHocCard.visual.spec.ts-snapshots/AdHocCard-mobile-safari-linux.png differ diff --git a/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts new file mode 100644 index 0000000..dfa754a --- /dev/null +++ b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts @@ -0,0 +1,11 @@ +import { test, expect } from '@playwright/test'; + +test('visual regression', async ({ page }) => { + await page.goto( + '/iframe.html?args=&id=components-cards-discordcard--default', + ); + + await expect(page.locator('#storybook-root')).toHaveScreenshot( + 'DiscordCard.png', + ); +}); diff --git a/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-desktop-chrome-linux.png b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-desktop-chrome-linux.png new file mode 100644 index 0000000..8f50ad2 Binary files /dev/null and b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-desktop-chrome-linux.png differ diff --git a/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-desktop-firefox-linux.png b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-desktop-firefox-linux.png new file mode 100644 index 0000000..85bc0f5 Binary files /dev/null and b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-desktop-firefox-linux.png differ diff --git a/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-desktop-safari-linux.png b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-desktop-safari-linux.png new file mode 100644 index 0000000..5ef91d5 Binary files /dev/null and b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-desktop-safari-linux.png differ diff --git a/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-mobile-chrome-linux.png b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-mobile-chrome-linux.png new file mode 100644 index 0000000..f8ec0dd Binary files /dev/null and b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-mobile-chrome-linux.png differ diff --git a/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-mobile-safari-linux.png b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-mobile-safari-linux.png new file mode 100644 index 0000000..d29819d Binary files /dev/null and b/src/components/DiscordCard/tests/DiscordCard.visual.spec.ts-snapshots/DiscordCard-mobile-safari-linux.png differ diff --git a/src/components/EventCard/tests/EventCard.visual.spec.ts b/src/components/EventCard/tests/EventCard.visual.spec.ts new file mode 100644 index 0000000..7e7505a --- /dev/null +++ b/src/components/EventCard/tests/EventCard.visual.spec.ts @@ -0,0 +1,11 @@ +import { test, expect } from '@playwright/test'; + +test('visual regression', async ({ page }) => { + await page.goto( + '/iframe.html?args=&id=components-cards-eventcard--default', + ); + + await expect(page.locator('#storybook-root')).toHaveScreenshot( + 'EventCard.png', + ); +}); diff --git a/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-desktop-chrome-linux.png b/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-desktop-chrome-linux.png new file mode 100644 index 0000000..5405795 Binary files /dev/null and b/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-desktop-chrome-linux.png differ diff --git a/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-desktop-firefox-linux.png b/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-desktop-firefox-linux.png new file mode 100644 index 0000000..fa328c2 Binary files /dev/null and b/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-desktop-firefox-linux.png differ diff --git a/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-desktop-safari-linux.png b/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-desktop-safari-linux.png new file mode 100644 index 0000000..8585da7 Binary files /dev/null and b/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-desktop-safari-linux.png differ diff --git a/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-mobile-chrome-linux.png b/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-mobile-chrome-linux.png new file mode 100644 index 0000000..df76816 Binary files /dev/null and b/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-mobile-chrome-linux.png differ diff --git a/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-mobile-safari-linux.png b/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-mobile-safari-linux.png new file mode 100644 index 0000000..e72d735 Binary files /dev/null and b/src/components/EventCard/tests/EventCard.visual.spec.ts-snapshots/EventCard-mobile-safari-linux.png differ diff --git a/src/components/FilteredGroupsShownMessage/FilteredGroupsShownMessage.stories.ts b/src/components/FilteredGroupsShownMessage/FilteredGroupsShownMessage.stories.ts new file mode 100644 index 0000000..149f104 --- /dev/null +++ b/src/components/FilteredGroupsShownMessage/FilteredGroupsShownMessage.stories.ts @@ -0,0 +1,33 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import FilteredGroupsShownMessage from './FilteredGroupsShownMessage'; + +const meta = { + title: 'Components/FilteredGroupsShownMessage', + component: FilteredGroupsShownMessage, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + argTypes: { + numberOfGroupsFiltered: { control: 'number' }, + numberOfPossibleGroups: { control: 'number' }, + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + numberOfGroupsFiltered: 5, + numberOfPossibleGroups: 10, + }, +}; + +export const NoGroupsFound: Story = { + args: { + numberOfGroupsFiltered: 0, + numberOfPossibleGroups: 10, + }, +}; diff --git a/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts new file mode 100644 index 0000000..06f3b05 --- /dev/null +++ b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts @@ -0,0 +1,11 @@ +import { test, expect } from '@playwright/test'; + +test('visual regression', async ({ page }) => { + await page.goto( + '/iframe.html?args=&id=components-filteredgroupsshownmessage--default', + ); + + await expect(page.locator('#storybook-root')).toHaveScreenshot( + 'FilteredGroupsShownMessage.png', + ); +}); diff --git a/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-desktop-chrome-linux.png b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-desktop-chrome-linux.png new file mode 100644 index 0000000..d040416 Binary files /dev/null and b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-desktop-chrome-linux.png differ diff --git a/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-desktop-firefox-linux.png b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-desktop-firefox-linux.png new file mode 100644 index 0000000..cc8341f Binary files /dev/null and b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-desktop-firefox-linux.png differ diff --git a/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-desktop-safari-linux.png b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-desktop-safari-linux.png new file mode 100644 index 0000000..6e3b0f4 Binary files /dev/null and b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-desktop-safari-linux.png differ diff --git a/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-mobile-chrome-linux.png b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-mobile-chrome-linux.png new file mode 100644 index 0000000..4cc33af Binary files /dev/null and b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-mobile-chrome-linux.png differ diff --git a/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-mobile-safari-linux.png b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-mobile-safari-linux.png new file mode 100644 index 0000000..e018912 Binary files /dev/null and b/src/components/FilteredGroupsShownMessage/tests/FilteredGroupsShownMessage.visual.spec.ts-snapshots/FilteredGroupsShownMessage-mobile-safari-linux.png differ diff --git a/src/components/Footer/tests/Footer.visual.spec.ts b/src/components/Footer/tests/Footer.visual.spec.ts new file mode 100644 index 0000000..18448cc --- /dev/null +++ b/src/components/Footer/tests/Footer.visual.spec.ts @@ -0,0 +1,9 @@ +import { test, expect } from '@playwright/test'; + +test('visual regression', async ({ page }) => { + await page.goto('/iframe.html?args=&id=components-footer--default'); + + await expect(page.locator('#storybook-root')).toHaveScreenshot( + 'Footer.png', + ); +}); diff --git a/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-desktop-chrome-linux.png b/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-desktop-chrome-linux.png new file mode 100644 index 0000000..93ac3b9 Binary files /dev/null and b/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-desktop-chrome-linux.png differ diff --git a/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-desktop-firefox-linux.png b/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-desktop-firefox-linux.png new file mode 100644 index 0000000..ad36851 Binary files /dev/null and b/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-desktop-firefox-linux.png differ diff --git a/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-desktop-safari-linux.png b/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-desktop-safari-linux.png new file mode 100644 index 0000000..6b779c6 Binary files /dev/null and b/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-desktop-safari-linux.png differ diff --git a/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-mobile-chrome-linux.png b/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-mobile-chrome-linux.png new file mode 100644 index 0000000..51bbf2e Binary files /dev/null and b/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-mobile-chrome-linux.png differ diff --git a/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-mobile-safari-linux.png b/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-mobile-safari-linux.png new file mode 100644 index 0000000..ae94901 Binary files /dev/null and b/src/components/Footer/tests/Footer.visual.spec.ts-snapshots/Footer-mobile-safari-linux.png differ diff --git a/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-desktop-chrome-linux.png b/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-desktop-chrome-linux.png new file mode 100644 index 0000000..7ea3e04 Binary files /dev/null and b/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-desktop-chrome-linux.png differ diff --git a/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-desktop-firefox-linux.png b/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-desktop-firefox-linux.png new file mode 100644 index 0000000..c0da418 Binary files /dev/null and b/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-desktop-firefox-linux.png differ diff --git a/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-desktop-safari-linux.png b/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-desktop-safari-linux.png new file mode 100644 index 0000000..52f2586 Binary files /dev/null and b/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-desktop-safari-linux.png differ diff --git a/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-mobile-chrome-linux.png b/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-mobile-chrome-linux.png new file mode 100644 index 0000000..b5b7b2d Binary files /dev/null and b/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-mobile-chrome-linux.png differ diff --git a/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-mobile-safari-linux.png b/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-mobile-safari-linux.png new file mode 100644 index 0000000..1794c16 Binary files /dev/null and b/src/components/GroupCard/tests/GroupCard.spec.ts-snapshots/group-card-mobile-safari-linux.png differ diff --git a/src/components/GroupCard/tests/GroupCard.visual.spec.ts b/src/components/GroupCard/tests/GroupCard.visual.spec.ts new file mode 100644 index 0000000..b629650 --- /dev/null +++ b/src/components/GroupCard/tests/GroupCard.visual.spec.ts @@ -0,0 +1,11 @@ +import { test, expect } from '@playwright/test'; + +test('visual regression', async ({ page }) => { + await page.goto( + '/iframe.html?args=&id=components-cards-groupcard--default', + ); + + await expect(page.locator('#storybook-root')).toHaveScreenshot( + 'GroupCard.png', + ); +}); diff --git a/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-desktop-chrome-linux.png b/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-desktop-chrome-linux.png new file mode 100644 index 0000000..7ea3e04 Binary files /dev/null and b/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-desktop-chrome-linux.png differ diff --git a/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-desktop-firefox-linux.png b/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-desktop-firefox-linux.png new file mode 100644 index 0000000..c0da418 Binary files /dev/null and b/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-desktop-firefox-linux.png differ diff --git a/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-desktop-safari-linux.png b/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-desktop-safari-linux.png new file mode 100644 index 0000000..52f2586 Binary files /dev/null and b/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-desktop-safari-linux.png differ diff --git a/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-mobile-chrome-linux.png b/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-mobile-chrome-linux.png new file mode 100644 index 0000000..b5b7b2d Binary files /dev/null and b/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-mobile-chrome-linux.png differ diff --git a/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-mobile-safari-linux.png b/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-mobile-safari-linux.png new file mode 100644 index 0000000..1794c16 Binary files /dev/null and b/src/components/GroupCard/tests/GroupCard.visual.spec.ts-snapshots/GroupCard-mobile-safari-linux.png differ diff --git a/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts new file mode 100644 index 0000000..56c6b7e --- /dev/null +++ b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts @@ -0,0 +1,11 @@ +import { test, expect } from '@playwright/test'; + +test('visual regression', async ({ page }) => { + await page.goto( + '/iframe.html?args=&id=components-grouplistingfeed--default', + ); + + await expect(page.locator('#storybook-root')).toHaveScreenshot( + 'GroupListingFeed.png', + ); +}); diff --git a/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-desktop-chrome-linux.png b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-desktop-chrome-linux.png new file mode 100644 index 0000000..fa92e90 Binary files /dev/null and b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-desktop-chrome-linux.png differ diff --git a/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-desktop-firefox-linux.png b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-desktop-firefox-linux.png new file mode 100644 index 0000000..ad75fc2 Binary files /dev/null and b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-desktop-firefox-linux.png differ diff --git a/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-desktop-safari-linux.png b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-desktop-safari-linux.png new file mode 100644 index 0000000..c39e046 Binary files /dev/null and b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-desktop-safari-linux.png differ diff --git a/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-mobile-chrome-linux.png b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-mobile-chrome-linux.png new file mode 100644 index 0000000..59c2135 Binary files /dev/null and b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-mobile-chrome-linux.png differ diff --git a/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-mobile-safari-linux.png b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-mobile-safari-linux.png new file mode 100644 index 0000000..1e1ee3b Binary files /dev/null and b/src/components/GroupListingFeed/tests/GroupListingFeed.visual.spec.ts-snapshots/GroupListingFeed-mobile-safari-linux.png differ diff --git a/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts new file mode 100644 index 0000000..747225f --- /dev/null +++ b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts @@ -0,0 +1,11 @@ +import { test, expect } from '@playwright/test'; + +test('visual regression', async ({ page }) => { + await page.goto( + '/iframe.html?args=&id=components-grouplistingmap--default', + ); + + await expect(page.locator('#storybook-root')).toHaveScreenshot( + 'GroupListingMap.png', + ); +}); diff --git a/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-desktop-chrome-linux.png b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-desktop-chrome-linux.png new file mode 100644 index 0000000..edd8dfb Binary files /dev/null and b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-desktop-chrome-linux.png differ diff --git a/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-desktop-firefox-linux.png b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-desktop-firefox-linux.png new file mode 100644 index 0000000..f5b6959 Binary files /dev/null and b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-desktop-firefox-linux.png differ diff --git a/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-desktop-safari-linux.png b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-desktop-safari-linux.png new file mode 100644 index 0000000..16f8ed2 Binary files /dev/null and b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-desktop-safari-linux.png differ diff --git a/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-mobile-chrome-linux.png b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-mobile-chrome-linux.png new file mode 100644 index 0000000..584f2af Binary files /dev/null and b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-mobile-chrome-linux.png differ diff --git a/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-mobile-safari-linux.png b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-mobile-safari-linux.png new file mode 100644 index 0000000..a1b2193 Binary files /dev/null and b/src/components/GroupListingMap/tests/GroupListingMap.visual.spec.ts-snapshots/GroupListingMap-mobile-safari-linux.png differ diff --git a/src/components/Header/tests/Header.visual.spec.ts b/src/components/Header/tests/Header.visual.spec.ts new file mode 100644 index 0000000..a03a4d5 --- /dev/null +++ b/src/components/Header/tests/Header.visual.spec.ts @@ -0,0 +1,9 @@ +import { test, expect } from '@playwright/test'; + +test('visual regression', async ({ page }) => { + await page.goto('/iframe.html?args=&id=components-header--default'); + + await expect(page.locator('#storybook-root')).toHaveScreenshot( + 'Header.png', + ); +}); diff --git a/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-desktop-chrome-linux.png b/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-desktop-chrome-linux.png new file mode 100644 index 0000000..9a8bbec Binary files /dev/null and b/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-desktop-chrome-linux.png differ diff --git a/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-desktop-firefox-linux.png b/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-desktop-firefox-linux.png new file mode 100644 index 0000000..0da7f09 Binary files /dev/null and b/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-desktop-firefox-linux.png differ diff --git a/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-desktop-safari-linux.png b/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-desktop-safari-linux.png new file mode 100644 index 0000000..4e53974 Binary files /dev/null and b/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-desktop-safari-linux.png differ diff --git a/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-mobile-chrome-linux.png b/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-mobile-chrome-linux.png new file mode 100644 index 0000000..aba64bd Binary files /dev/null and b/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-mobile-chrome-linux.png differ diff --git a/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-mobile-safari-linux.png b/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-mobile-safari-linux.png new file mode 100644 index 0000000..0f62e39 Binary files /dev/null and b/src/components/Header/tests/Header.visual.spec.ts-snapshots/Header-mobile-safari-linux.png differ diff --git a/src/components/Link/tests/Link.visual.spec.ts b/src/components/Link/tests/Link.visual.spec.ts new file mode 100644 index 0000000..63d085e --- /dev/null +++ b/src/components/Link/tests/Link.visual.spec.ts @@ -0,0 +1,7 @@ +import { test, expect } from '@playwright/test'; + +test('visual regression', async ({ page }) => { + await page.goto('/iframe.html?args=&id=components-link--default'); + + await expect(page.locator('#storybook-root')).toHaveScreenshot('Link.png'); +}); diff --git a/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-desktop-chrome-linux.png b/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-desktop-chrome-linux.png new file mode 100644 index 0000000..0342a6f Binary files /dev/null and b/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-desktop-chrome-linux.png differ diff --git a/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-desktop-firefox-linux.png b/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-desktop-firefox-linux.png new file mode 100644 index 0000000..d38a772 Binary files /dev/null and b/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-desktop-firefox-linux.png differ diff --git a/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-desktop-safari-linux.png b/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-desktop-safari-linux.png new file mode 100644 index 0000000..3433d7a Binary files /dev/null and b/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-desktop-safari-linux.png differ diff --git a/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-mobile-chrome-linux.png b/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-mobile-chrome-linux.png new file mode 100644 index 0000000..f666fac Binary files /dev/null and b/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-mobile-chrome-linux.png differ diff --git a/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-mobile-safari-linux.png b/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-mobile-safari-linux.png new file mode 100644 index 0000000..2a24e12 Binary files /dev/null and b/src/components/Link/tests/Link.visual.spec.ts-snapshots/Link-mobile-safari-linux.png differ diff --git a/src/components/Map/tests/Map.visual.spec.ts b/src/components/Map/tests/Map.visual.spec.ts new file mode 100644 index 0000000..1c3b100 --- /dev/null +++ b/src/components/Map/tests/Map.visual.spec.ts @@ -0,0 +1,12 @@ +// Disabled due to flakiness +// import { test, expect } from '@playwright/test'; + +// test('visual regression', async ({ page }) => { +// await page.goto( +// '/iframe.html?args=&id=components-map--default', +// ); + +// await expect(page.locator('#storybook-root')).toHaveScreenshot( +// 'Map.png', +// ); +// }); diff --git a/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-desktop-chrome-linux.png b/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-desktop-chrome-linux.png new file mode 100644 index 0000000..a2b69f3 Binary files /dev/null and b/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-desktop-chrome-linux.png differ diff --git a/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-desktop-firefox-linux.png b/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-desktop-firefox-linux.png new file mode 100644 index 0000000..0c4e8ef Binary files /dev/null and b/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-desktop-firefox-linux.png differ diff --git a/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-desktop-safari-linux.png b/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-desktop-safari-linux.png new file mode 100644 index 0000000..9b1eacf Binary files /dev/null and b/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-desktop-safari-linux.png differ diff --git a/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-mobile-chrome-linux.png b/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-mobile-chrome-linux.png new file mode 100644 index 0000000..506c49a Binary files /dev/null and b/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-mobile-chrome-linux.png differ diff --git a/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-mobile-safari-linux.png b/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-mobile-safari-linux.png new file mode 100644 index 0000000..0f341ac Binary files /dev/null and b/src/components/Map/tests/Map.visual.spec.ts-snapshots/Map-mobile-safari-linux.png differ diff --git a/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts new file mode 100644 index 0000000..d455f79 --- /dev/null +++ b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts @@ -0,0 +1,12 @@ +// Disabled due to flakiness +// import { test, expect } from '@playwright/test'; + +// test('visual regression', async ({ page }) => { +// await page.goto( +// '/iframe.html?args=&id=components-singlemarkermap--default', +// ); + +// await expect(page.locator('#storybook-root')).toHaveScreenshot( +// 'SingleMarkerMap.png', +// ); +// }); diff --git a/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-desktop-chrome-linux.png b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-desktop-chrome-linux.png new file mode 100644 index 0000000..a35d0f5 Binary files /dev/null and b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-desktop-chrome-linux.png differ diff --git a/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-desktop-firefox-linux.png b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-desktop-firefox-linux.png new file mode 100644 index 0000000..6b26ca1 Binary files /dev/null and b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-desktop-firefox-linux.png differ diff --git a/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-desktop-safari-linux.png b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-desktop-safari-linux.png new file mode 100644 index 0000000..2aa93b0 Binary files /dev/null and b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-desktop-safari-linux.png differ diff --git a/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-mobile-chrome-linux.png b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-mobile-chrome-linux.png new file mode 100644 index 0000000..33d9d61 Binary files /dev/null and b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-mobile-chrome-linux.png differ diff --git a/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-mobile-safari-linux.png b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-mobile-safari-linux.png new file mode 100644 index 0000000..99cf471 Binary files /dev/null and b/src/components/SingleMarkerMap/tests/SingleMarkerMap.visual.spec.ts-snapshots/SingleMarkerMap-mobile-safari-linux.png differ diff --git a/src/stories/mocks.ts b/src/stories/mocks.ts index 9385f8b..2d6c197 100644 --- a/src/stories/mocks.ts +++ b/src/stories/mocks.ts @@ -13,18 +13,36 @@ const createMockEvent = ( start: string, end: string, frequency: string, -): Event => ({ - time: { weekday, start, end, frequency }, - location: { - address: '123 Example Street, Bristol, BS19 1AA', - latitude: (51.456098 + Math.random() / 50 - 0.01).toString(), - longitude: (-2.596541 + Math.random() / 50 - 0.01).toString(), - googleMapsLink: 'https://goo.gl/maps/example', - }, - cost: { sessionPrice: 10, details: 'Per session' }, - booking: { required: 'Advised', details: 'Booking is recommended' }, - url: 'https://example.com/event', -}); + locationIndex: number, +): Event => { + const locations = [ + { + address: '123 Example Street, Bristol, BS19 1AA', + latitude: '51.456098', + longitude: '-2.590541', + googleMapsLink: 'https://goo.gl/maps/example1', + }, + { + address: '456 Example Street, Bristol, BS19 1AB', + latitude: '51.458198', + longitude: '-2.596641', + googleMapsLink: 'https://goo.gl/maps/example2', + }, + { + address: '789 Example Street, Bristol, BS19 1AC', + latitude: '51.450298', + longitude: '-2.601741', + googleMapsLink: 'https://goo.gl/maps/example3', + }, + ]; + return { + time: { weekday, start, end, frequency }, + location: locations[locationIndex], + cost: { sessionPrice: 10, details: 'Per session' }, + booking: { required: 'Advised', details: 'Booking is recommended' }, + url: 'https://example.com/event', + }; +}; export const MOCK_EVENTS: Event[] = [ createMockEvent( @@ -32,18 +50,21 @@ export const MOCK_EVENTS: Event[] = [ '2024-07-22T18:00:00Z', '2024-07-22T20:00:00Z', 'Weekly', + 0, ), createMockEvent( 'Wednesday', '2024-07-24T19:00:00Z', '2024-07-24T21:00:00Z', 'Weekly', + 1, ), createMockEvent( 'Friday', '2024-07-26T17:30:00Z', '2024-07-26T19:30:00Z', 'Weekly', + 2, ), ];