From e5ba14fc2b4c9130490e2d265a8a902b8d7688c1 Mon Sep 17 00:00:00 2001 From: code-mattclaffey Date: Tue, 20 May 2025 09:44:08 +0100 Subject: [PATCH 1/5] fix: security auditing --- .github/workflows/main.yml | 53 + package-lock.json | 1567 ++++++----------- package.json | 4 +- .../exercise.tsx | 1 + 4 files changed, 584 insertions(+), 1041 deletions(-) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..9593f00 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,53 @@ +name: Quality checks + +on: + push: + branches: + - main + - feature/** + - v2 + pull_request: + branches: + - main + +jobs: + quality_checks: + name: Quality checks + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + shard: [1] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Cache + uses: actions/cache@v4 + with: + path: | + ~/.npm + ${{ github.workspace }}/dist/cache + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} + restore-keys: | + ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- + + - name: Setup Node.js environment + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install + run: npm ci + + - name: Security Audit Checks + run: npm run audit + + - name: Static testing + run: npm run lint + + - name: Build Website + run: npm run build + + - name: Build Storybook + run: npm run build-storybook diff --git a/package-lock.json b/package-lock.json index 2224de6..7337777 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,7 @@ "@typescript-eslint/parser": "^7.13.1", "@vitejs/plugin-react": "^4.3.1", "autoprefixer": "^10.4.19", + "better-npm-audit": "^3.11.0", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", @@ -80,13 +81,15 @@ } }, "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==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" @@ -284,19 +287,21 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@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==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -311,38 +316,28 @@ } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz", + "integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "node_modules/@babel/parser": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz", + "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/types": "^7.27.1" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -558,25 +553,24 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz", + "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -604,14 +598,14 @@ } }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz", + "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -2892,600 +2886,49 @@ } }, "node_modules/@storybook/core": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.4.7.tgz", - "integrity": "sha512-7Z8Z0A+1YnhrrSXoKKwFFI4gnsLbWzr8fnDCU6+6HlDukFYh8GHRcZ9zKfqmy6U3hw2h8H5DrHsxWfyaYUUOoA==", - "dev": true, - "dependencies": { - "@storybook/csf": "^0.1.11", - "better-opn": "^3.0.2", - "browser-assert": "^1.2.1", - "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0", - "esbuild-register": "^3.5.0", - "jsdoc-type-pratt-parser": "^4.0.0", - "process": "^0.11.10", - "recast": "^0.23.5", - "semver": "^7.6.2", - "util": "^0.12.5", - "ws": "^8.2.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "prettier": "^2 || ^3" - }, - "peerDependenciesMeta": { - "prettier": { - "optional": true - } - } - }, - "node_modules/@storybook/core-common": { - "version": "8.1.10", - "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-8.1.10.tgz", - "integrity": "sha512-+0GhgDRQwUlXu1lY77NdLnVBVycCEW0DG7eu7rvLYYkTyNRxbdl2RWsQpjr/j4sxqT6u82l9/b+RWpmsl4MgMQ==", - "dev": true, - "dependencies": { - "@storybook/core-events": "8.1.10", - "@storybook/csf-tools": "8.1.10", - "@storybook/node-logger": "8.1.10", - "@storybook/types": "8.1.10", - "@yarnpkg/fslib": "2.10.3", - "@yarnpkg/libzip": "2.3.0", - "chalk": "^4.1.0", - "cross-spawn": "^7.0.3", - "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0", - "esbuild-register": "^3.5.0", - "execa": "^5.0.0", - "file-system-cache": "2.3.0", - "find-cache-dir": "^3.0.0", - "find-up": "^5.0.0", - "fs-extra": "^11.1.0", - "glob": "^10.0.0", - "handlebars": "^4.7.7", - "lazy-universal-dotenv": "^4.0.0", - "node-fetch": "^2.0.0", - "picomatch": "^2.3.0", - "pkg-dir": "^5.0.0", - "prettier-fallback": "npm:prettier@^3", - "pretty-hrtime": "^1.0.3", - "resolve-from": "^5.0.0", - "semver": "^7.3.7", - "tempy": "^3.1.0", - "tiny-invariant": "^1.3.1", - "ts-dedent": "^2.0.0", - "util": "^0.12.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "prettier": "^2 || ^3" - }, - "peerDependenciesMeta": { - "prettier": { - "optional": true - } - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.14.tgz", + "integrity": "sha512-1P/w4FSNRqP8j3JQBOi3yGt8PVOgSRbP66Ok520T78eJBeqx9ukCfl912PQZ7SPbW3TIunBwLXMZOjZwBB/JmA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/core-common/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@storybook/core-common/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@storybook/core-common/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@storybook/core-common/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@storybook/core-common/node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, - "node_modules/@storybook/core-common/node_modules/glob": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", - "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@storybook/core-common/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/core-common/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/@storybook/core-common/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" + "license": "MIT", + "dependencies": { + "@storybook/theming": "8.6.14", + "better-opn": "^3.0.2", + "browser-assert": "^1.2.1", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", + "esbuild-register": "^3.5.0", + "jsdoc-type-pratt-parser": "^4.0.0", + "process": "^0.11.10", + "recast": "^0.23.5", + "semver": "^7.6.2", + "util": "^0.12.5", + "ws": "^8.2.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "prettier": "^2 || ^3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } } }, - "node_modules/@storybook/core-common/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@storybook/core-common": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-8.6.14.tgz", + "integrity": "sha512-Q1rSAFnuZcisoWqE1tmLSsXtPUIC0BC00VPCdpvoeNBOyBbye4JCeARbqr3utQSMrXJJ25D8Qt9rc0f2gwbg2w==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" } }, "node_modules/@storybook/core-events": { @@ -3502,6 +2945,20 @@ "url": "https://opencollective.com/storybook" } }, + "node_modules/@storybook/core/node_modules/@storybook/theming": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.14.tgz", + "integrity": "sha512-r4y+LsiB37V5hzpQo+BM10PaCsp7YlZ0YcZzQP1OCkPlYXmUAFy2VvDKaFRpD8IeNPKug2u4iFm/laDEbs03dg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" + } + }, "node_modules/@storybook/csf": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.13.tgz", @@ -3612,16 +3069,6 @@ "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" } }, - "node_modules/@storybook/node-logger": { - "version": "8.1.10", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-8.1.10.tgz", - "integrity": "sha512-djgbAROgGAvz/gr49egBxCHn1+rui57e76qa9aOMPzEBcxsGrnnKKp0uNdiNt4M7Xv6S2QHbJ2SfOlHhWmMeaA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, "node_modules/@storybook/preview-api": { "version": "8.4.7", "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.4.7.tgz", @@ -4317,12 +3764,6 @@ "@types/node": "*" } }, - "node_modules/@types/emscripten": { - "version": "1.39.13", - "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.13.tgz", - "integrity": "sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw==", - "dev": true - }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -4856,32 +4297,6 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/@yarnpkg/fslib": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.10.3.tgz", - "integrity": "sha512-41H+Ga78xT9sHvWLlFOZLIhtU6mTGZ20pZ29EiZa97vnxdohJD2AF42rCoAoWfqUz486xY6fhjMH+DYEM9r14A==", - "dev": true, - "dependencies": { - "@yarnpkg/libzip": "^2.3.0", - "tslib": "^1.13.0" - }, - "engines": { - "node": ">=12 <14 || 14.2 - 14.9 || >14.10.0" - } - }, - "node_modules/@yarnpkg/libzip": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.3.0.tgz", - "integrity": "sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg==", - "dev": true, - "dependencies": { - "@types/emscripten": "^1.39.6", - "tslib": "^1.13.0" - }, - "engines": { - "node": ">=12 <14 || 14.2 - 14.9 || >14.10.0" - } - }, "node_modules/acorn": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", @@ -4999,12 +4414,6 @@ "node": ">= 8" } }, - "node_modules/app-root-dir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/app-root-dir/-/app-root-dir-1.0.2.tgz", - "integrity": "sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==", - "dev": true - }, "node_modules/append-transform": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", @@ -5082,6 +4491,16 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -5130,6 +4549,7 @@ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -5141,10 +4561,11 @@ } }, "node_modules/axios": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", "dev": true, + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -5343,11 +4764,32 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/better-npm-audit": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/better-npm-audit/-/better-npm-audit-3.11.0.tgz", + "integrity": "sha512-/Pt05DK6HQaRjWDc5McsCkJBZYfhgQGneKnxzPJExtRq38NttO1Hm30m0GVQeZogE94LVNBVrhWwVsoCo+at3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^8.0.0", + "dayjs": "^1.10.6", + "lodash.get": "^4.4.2", + "semver": "^7.6.3", + "table": "^6.7.1" + }, + "bin": { + "better-npm-audit": "index.js" + }, + "engines": { + "node": ">= 8.12" + } + }, "node_modules/better-opn": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", "dev": true, + "license": "MIT", "dependencies": { "open": "^8.0.4" }, @@ -5469,16 +4911,47 @@ } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -5829,6 +5302,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -5952,33 +5435,6 @@ "node": ">= 8" } }, - "node_modules/crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "dev": true, - "dependencies": { - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/crypto-random-string/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/css-color-keywords": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", @@ -6034,6 +5490,13 @@ "node": ">=0.8" } }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "dev": true, + "license": "MIT" + }, "node_modules/debug": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", @@ -6128,6 +5591,7 @@ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -6145,6 +5609,7 @@ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6298,25 +5763,19 @@ "domelementtype": "1" } }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, - "engines": { - "node": ">=12" + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/dotenv-expand": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", - "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", - "dev": true, "engines": { - "node": ">=12" + "node": ">= 0.4" } }, "node_modules/eastasianwidth": { @@ -6365,13 +5824,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -6381,6 +5838,20 @@ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, "engines": { "node": ">= 0.4" } @@ -6430,10 +5901,11 @@ } }, "node_modules/esbuild-register": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.5.0.tgz", - "integrity": "sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz", + "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -7021,6 +6493,23 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -7380,12 +6869,19 @@ } }, "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, + "license": "MIT", "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/foreground-child": { @@ -7542,16 +7038,22 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -7569,6 +7071,20 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -7706,12 +7222,13 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7729,27 +7246,6 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -7764,6 +7260,7 @@ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -7771,23 +7268,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7800,6 +7286,7 @@ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -7902,6 +7389,12 @@ "node": "*" } }, + "node_modules/highlightjs-vue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz", + "integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==", + "license": "CC0-1.0" + }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -8115,13 +7608,14 @@ } }, "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -8153,6 +7647,7 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8189,6 +7684,7 @@ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, + "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -8227,12 +7723,16 @@ } }, "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -8277,7 +7777,26 @@ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-stream": { @@ -8293,12 +7812,13 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, + "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -8327,6 +7847,7 @@ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, + "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, @@ -10652,6 +10173,7 @@ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.0.0" } @@ -10740,20 +10262,6 @@ "node": ">=6" } }, - "node_modules/lazy-universal-dotenv": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/lazy-universal-dotenv/-/lazy-universal-dotenv-4.0.0.tgz", - "integrity": "sha512-aXpZJRnTkpK6gQ/z4nk+ZBLd/Qdp118cvPruLSIQzQNRhKwEcdXCOzXuF55VDqIiuAaY3UGZ10DJtvZzDcvsxg==", - "dev": true, - "dependencies": { - "app-root-dir": "^1.0.2", - "dotenv": "^16.0.0", - "dotenv-expand": "^10.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -10818,12 +10326,27 @@ "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", "dev": true }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "license": "MIT" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -10923,6 +10446,16 @@ "integrity": "sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==", "dev": true }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/memoizerific": { "version": "1.11.3", "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", @@ -11084,32 +10617,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "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==", - "dev": true, - "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-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -11454,6 +10961,7 @@ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, + "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -11723,18 +11231,6 @@ "node": ">= 6" } }, - "node_modules/pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "dependencies": { - "find-up": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/playwright": { "version": "1.44.1", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz", @@ -11792,10 +11288,11 @@ } }, "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -11973,22 +11470,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/prettier-fallback": { - "name": "prettier", - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/pretty-format": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", @@ -12017,19 +11498,11 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", "engines": { "node": ">=6" } @@ -12039,6 +11512,7 @@ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6.0" } @@ -12303,12 +11777,14 @@ } }, "node_modules/react-syntax-highlighter": { - "version": "15.5.0", - "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", - "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==", + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.6.1.tgz", + "integrity": "sha512-OqJ2/vL7lEeV5zTJyG7kmARppUjiB9h9udl4qHQjjgEos66z00Ia0OckwYfRxCSFrW8RJIBnsBwQsHZbVPspqg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.3.1", "highlight.js": "^10.4.1", + "highlightjs-vue": "^1.0.0", "lowlight": "^1.17.0", "prismjs": "^1.27.0", "refractor": "^3.6.0" @@ -12432,11 +11908,6 @@ "node": ">=6" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, "node_modules/release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -12458,6 +11929,16 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -12664,6 +12145,24 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -12673,10 +12172,11 @@ } }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -12700,6 +12200,7 @@ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -12759,6 +12260,60 @@ "node": ">=8" } }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -12855,12 +12410,13 @@ } }, "node_modules/storybook": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.4.7.tgz", - "integrity": "sha512-RP/nMJxiWyFc8EVMH5gp20ID032Wvk+Yr3lmKidoegto5Iy+2dVQnUoElZb2zpbVXNHWakGuAkfI0dY1Hfp/vw==", + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.14.tgz", + "integrity": "sha512-sVKbCj/OTx67jhmauhxc2dcr1P+yOgz/x3h0krwjyMgdc5Oubvxyg4NYDZmzAw+ym36g/lzH8N0Ccp4dwtdfxw==", "dev": true, + "license": "MIT", "dependencies": { - "@storybook/core": "8.4.7" + "@storybook/core": "8.6.14" }, "bin": { "getstorybook": "bin/index.cjs", @@ -13125,6 +12681,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/table": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, "node_modules/tailwindcss": { "version": "3.4.5", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.5.tgz", @@ -13171,57 +12768,6 @@ "memoizerific": "^1.11.3" } }, - "node_modules/temp-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", - "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", - "dev": true, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/tempy": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", - "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", - "dev": true, - "dependencies": { - "is-stream": "^3.0.0", - "temp-dir": "^3.0.0", - "type-fest": "^2.12.2", - "unique-string": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -13317,15 +12863,6 @@ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -13338,12 +12875,6 @@ "node": ">=8.0" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -13476,40 +13007,12 @@ "node": ">=14.17" } }, - "node_modules/uglify-js": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", - "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, "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 }, - "node_modules/unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "dev": true, - "dependencies": { - "crypto-random-string": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -13629,6 +13132,7 @@ "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -13671,10 +13175,11 @@ } }, "node_modules/vite": { - "version": "5.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", - "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "version": "5.4.19", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", + "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -13808,12 +13313,6 @@ "makeerror": "1.0.12" } }, - "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==", - "dev": true - }, "node_modules/webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", @@ -13829,16 +13328,6 @@ "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", "dev": true }, - "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==", - "dev": true, - "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", @@ -13861,15 +13350,18 @@ "dev": true }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -13888,12 +13380,6 @@ "node": ">=0.10.0" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -14031,10 +13517,11 @@ "dev": true }, "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index 92f22ff..10bdd62 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "preview": "vite preview", "storybook": "storybook dev -p 6006", "build-storybook": "npm run build && storybook build -o dist/storybook", - "test": "test-storybook" + "test": "test-storybook", + "audit": "better-npm-audit audit --production --exclude 1102459" }, "dependencies": { "@vercel/analytics": "^1.3.1", @@ -40,6 +41,7 @@ "@typescript-eslint/parser": "^7.13.1", "@vitejs/plugin-react": "^4.3.1", "autoprefixer": "^10.4.19", + "better-npm-audit": "^3.11.0", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", diff --git a/src/course/02- lessons/04-PresentationalAndContainer/exercise.tsx b/src/course/02- lessons/04-PresentationalAndContainer/exercise.tsx index cb3d075..215ef12 100644 --- a/src/course/02- lessons/04-PresentationalAndContainer/exercise.tsx +++ b/src/course/02- lessons/04-PresentationalAndContainer/exercise.tsx @@ -22,6 +22,7 @@ interface IPaymentTemplate { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore +// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-empty-pattern const PaymentTemplate = ({}: IPaymentTemplate) => null; // 1B πŸ‘¨πŸ»β€πŸ’» - Use the Payment template and pass down the props it needs From e4b6b12586d936ee33cd2e12314f9893bcd4b2c9 Mon Sep 17 00:00:00 2001 From: Matthew Claffey Date: Tue, 20 May 2025 11:52:09 +0100 Subject: [PATCH 2/5] feat: implement level grouping (#13) * feat: implement level grouping * chore: some content changes --- .storybook/main.ts | 8 +- .storybook/preview.tsx | 7 +- package.json | 2 +- src/course/01-introduction/01-Welcome.mdx | 34 +++--- .../01-introduction/02-GettingStarted.mdx | 2 +- .../01-introduction/03-LessonStructure.mdx | 10 +- .../exercise/exercise.stories.tsx | 51 +++++++++ .../exercise}/exercise.tsx | 2 +- .../final}/final.stories.tsx | 33 ++++-- .../ConditionalRendering/final}/final.tsx | 2 +- .../ConditionalRendering}/lesson.mdx | 4 +- .../Hooks}/components.tsx | 6 +- .../Hooks/exercise}/exercise.stories.tsx | 2 +- .../Hooks/exercise}/exercise.tsx | 2 +- .../01-Bronze/Hooks/final}/final.stories.tsx | 2 +- .../01-Bronze/Hooks/final}/final.tsx | 2 +- .../{05-Hooks => 01-Bronze/Hooks}/lesson.mdx | 2 +- .../exercise}/exercise.stories.tsx | 2 +- .../exercise}/exercise.tsx | 8 +- .../final}/final.stories.tsx | 3 +- .../final}/final.tsx | 8 +- .../PresentationalAndContainer}/lesson.mdx | 2 +- .../PresentationalAndContainer}/mocks.ts | 0 .../exercise}/exercise.stories.tsx | 2 +- .../PropsCombination/exercise}/exercise.tsx | 0 .../PropsCombination/final}/final.stories.tsx | 2 +- .../PropsCombination/final}/final.tsx | 0 .../PropsCombination}/lesson.mdx | 2 +- .../Slots/exercise}/exercise.stories.tsx | 2 +- .../Slots/exercise}/exercise.tsx | 0 .../01-Bronze/Slots/final}/final.stories.tsx | 2 +- .../01-Bronze/Slots/final}/final.tsx | 2 +- .../Slots}/icons/index.tsx | 0 .../{11-Slots => 01-Bronze/Slots}/lesson.mdx | 2 +- .../exercise.stories.tsx | 38 ------- .../exercise}/components/Accordion.tsx | 0 .../exercise}/components/Accoridon.module.css | 0 .../exercise}/components/ChevronDown.tsx | 0 .../Compound/exercise}/exercise.stories.tsx | 2 +- .../Compound/exercise}/exercise.tsx | 0 .../Compound/final}/components/Accordion.tsx | 0 .../final}/components/Accoridon.module.css | 0 .../final}/components/ChevronDown.tsx | 0 .../Compound/final}/final.stories.tsx | 2 +- .../02-Silver/Compound/final}/final.tsx | 0 .../Compound}/lesson.mdx | 2 +- .../Controlled/exercise}/exercise.stories.tsx | 3 +- .../Controlled/exercise}/exercise.tsx | 2 +- .../Controlled/final/final.stories.tsx | 20 ++++ .../02-Silver/Controlled/final}/final.tsx | 2 +- .../Controlled}/lesson.mdx | 2 +- .../Portals/exercise}/components/modal.tsx | 2 +- .../Portals/exercise}/exercise.stories.tsx | 2 +- .../Portals/exercise}/exercise.tsx | 2 +- .../Portals/final}/components/modal.tsx | 2 +- .../Portals/final}/final.stories.tsx | 2 +- .../02-Silver/Portals/final}/final.tsx | 2 +- .../Portals}/lesson.mdx | 2 +- .../Provider/exercise}/Provider.tsx | 0 .../Provider/exercise}/exercise.stories.tsx | 2 +- .../Provider/exercise}/exercise.tsx | 0 .../02-Silver/Provider/final}/Provider.tsx | 2 +- .../Provider/final}/final.stories.tsx | 2 +- .../02-Silver/Provider/final}/final.tsx | 0 .../Provider}/lesson.mdx | 2 +- .../exercise}/exercise.stories.tsx | 2 +- .../RenderProps/exercise}/exercise.tsx | 6 +- .../RenderProps/final}/final.stories.tsx | 2 +- .../02-Silver/RenderProps/final}/final.tsx | 6 +- .../RenderProps}/lesson.mdx | 2 +- .../exercise}/exercise.stories.tsx | 2 +- .../StateReducer/exercise}/exercise.tsx | 0 .../StateReducer/final}/final.stories.tsx | 2 +- .../02-Silver/StateReducer/final}/final.tsx | 2 +- .../StateReducer}/lesson.mdx | 2 +- .../exercise}/exercise.stories.tsx | 3 +- .../exercise}/exercise.tsx | 0 .../exercise}/withPokemon.tsx | 0 .../final}/final.stories.tsx | 2 +- .../01-HigherOrderComponents/final}/final.tsx | 2 +- .../final}/withPokemon.tsx | 2 +- .../01-HigherOrderComponents}/lesson.mdx | 2 +- .../04-PresentationalAndContainer/mocks.ts | 104 ------------------ .../02-solutions/05-Hooks/components.tsx | 30 ----- .../10-Compound/final.stories.tsx | 20 ---- .../02-solutions/11-Slots/icons/index.tsx | 31 ------ tsconfig.app.json | 5 +- tsconfig.node.json | 5 +- vite.config.ts | 6 +- 89 files changed, 215 insertions(+), 326 deletions(-) create mode 100644 src/course/02- lessons/01-Bronze/ConditionalRendering/exercise/exercise.stories.tsx rename src/course/02- lessons/{01-ConditionalRendering => 01-Bronze/ConditionalRendering/exercise}/exercise.tsx (92%) rename src/course/{02-solutions/01-ConditionalRendering => 02- lessons/01-Bronze/ConditionalRendering/final}/final.stories.tsx (51%) rename src/course/{02-solutions/01-ConditionalRendering => 02- lessons/01-Bronze/ConditionalRendering/final}/final.tsx (89%) rename src/course/02- lessons/{01-ConditionalRendering => 01-Bronze/ConditionalRendering}/lesson.mdx (90%) rename src/course/02- lessons/{05-Hooks => 01-Bronze/Hooks}/components.tsx (71%) rename src/course/02- lessons/{08-Provider => 01-Bronze/Hooks/exercise}/exercise.stories.tsx (88%) rename src/course/02- lessons/{05-Hooks => 01-Bronze/Hooks/exercise}/exercise.tsx (97%) rename src/course/{02-solutions/03-RenderProps => 02- lessons/01-Bronze/Hooks/final}/final.stories.tsx (88%) rename src/course/{02-solutions/05-Hooks => 02- lessons/01-Bronze/Hooks/final}/final.tsx (96%) rename src/course/02- lessons/{05-Hooks => 01-Bronze/Hooks}/lesson.mdx (98%) rename src/course/02- lessons/{04-PresentationalAndContainer => 01-Bronze/PresentationalAndContainer/exercise}/exercise.stories.tsx (86%) rename src/course/02- lessons/{04-PresentationalAndContainer => 01-Bronze/PresentationalAndContainer/exercise}/exercise.tsx (93%) rename src/course/{02-solutions/04-PresentationalAndContainer => 02- lessons/01-Bronze/PresentationalAndContainer/final}/final.stories.tsx (85%) rename src/course/{02-solutions/04-PresentationalAndContainer => 02- lessons/01-Bronze/PresentationalAndContainer/final}/final.tsx (93%) rename src/course/02- lessons/{04-PresentationalAndContainer => 01-Bronze/PresentationalAndContainer}/lesson.mdx (98%) rename src/course/02- lessons/{04-PresentationalAndContainer => 01-Bronze/PresentationalAndContainer}/mocks.ts (100%) rename src/course/02- lessons/{02-PropsCombination => 01-Bronze/PropsCombination/exercise}/exercise.stories.tsx (94%) rename src/course/02- lessons/{02-PropsCombination => 01-Bronze/PropsCombination/exercise}/exercise.tsx (100%) rename src/course/{02-solutions/02-PropsCombination => 02- lessons/01-Bronze/PropsCombination/final}/final.stories.tsx (94%) rename src/course/{02-solutions/02-PropsCombination => 02- lessons/01-Bronze/PropsCombination/final}/final.tsx (100%) rename src/course/02- lessons/{02-PropsCombination => 01-Bronze/PropsCombination}/lesson.mdx (96%) rename src/course/02- lessons/{11-Slots => 01-Bronze/Slots/exercise}/exercise.stories.tsx (90%) rename src/course/02- lessons/{11-Slots => 01-Bronze/Slots/exercise}/exercise.tsx (100%) rename src/course/{02-solutions/11-Slots => 02- lessons/01-Bronze/Slots/final}/final.stories.tsx (90%) rename src/course/{02-solutions/11-Slots => 02- lessons/01-Bronze/Slots/final}/final.tsx (96%) rename src/course/02- lessons/{11-Slots => 01-Bronze/Slots}/icons/index.tsx (100%) rename src/course/02- lessons/{11-Slots => 01-Bronze/Slots}/lesson.mdx (97%) delete mode 100644 src/course/02- lessons/01-ConditionalRendering/exercise.stories.tsx rename src/course/02- lessons/{10-Compound => 02-Silver/Compound/exercise}/components/Accordion.tsx (100%) rename src/course/02- lessons/{10-Compound => 02-Silver/Compound/exercise}/components/Accoridon.module.css (100%) rename src/course/02- lessons/{10-Compound => 02-Silver/Compound/exercise}/components/ChevronDown.tsx (100%) rename src/course/02- lessons/{06-Controlled => 02-Silver/Compound/exercise}/exercise.stories.tsx (86%) rename src/course/02- lessons/{10-Compound => 02-Silver/Compound/exercise}/exercise.tsx (100%) rename src/course/{02-solutions/10-Compound => 02- lessons/02-Silver/Compound/final}/components/Accordion.tsx (100%) rename src/course/{02-solutions/10-Compound => 02- lessons/02-Silver/Compound/final}/components/Accoridon.module.css (100%) rename src/course/{02-solutions/10-Compound => 02- lessons/02-Silver/Compound/final}/components/ChevronDown.tsx (100%) rename src/course/{02-solutions/06-Controlled => 02- lessons/02-Silver/Compound/final}/final.stories.tsx (86%) rename src/course/{02-solutions/10-Compound => 02- lessons/02-Silver/Compound/final}/final.tsx (100%) rename src/course/02- lessons/{10-Compound => 02-Silver/Compound}/lesson.mdx (96%) rename src/course/02- lessons/{05-Hooks => 02-Silver/Controlled/exercise}/exercise.stories.tsx (85%) rename src/course/02- lessons/{06-Controlled => 02-Silver/Controlled/exercise}/exercise.tsx (98%) create mode 100644 src/course/02- lessons/02-Silver/Controlled/final/final.stories.tsx rename src/course/{02-solutions/06-Controlled => 02- lessons/02-Silver/Controlled/final}/final.tsx (96%) rename src/course/02- lessons/{06-Controlled => 02-Silver/Controlled}/lesson.mdx (96%) rename src/course/02- lessons/{12-Portals => 02-Silver/Portals/exercise}/components/modal.tsx (96%) rename src/course/02- lessons/{12-Portals => 02-Silver/Portals/exercise}/exercise.stories.tsx (89%) rename src/course/02- lessons/{12-Portals => 02-Silver/Portals/exercise}/exercise.tsx (96%) rename src/course/{02-solutions/12-Portals => 02- lessons/02-Silver/Portals/final}/components/modal.tsx (95%) rename src/course/{02-solutions/12-Portals => 02- lessons/02-Silver/Portals/final}/final.stories.tsx (89%) rename src/course/{02-solutions/12-Portals => 02- lessons/02-Silver/Portals/final}/final.tsx (96%) rename src/course/02- lessons/{12-Portals => 02-Silver/Portals}/lesson.mdx (96%) rename src/course/02- lessons/{08-Provider => 02-Silver/Provider/exercise}/Provider.tsx (100%) rename src/course/02- lessons/{09-StateReducer => 02-Silver/Provider/exercise}/exercise.stories.tsx (88%) rename src/course/02- lessons/{08-Provider => 02-Silver/Provider/exercise}/exercise.tsx (100%) rename src/course/{02-solutions/08-Provider => 02- lessons/02-Silver/Provider/final}/Provider.tsx (95%) rename src/course/{02-solutions/09-StateReducer => 02- lessons/02-Silver/Provider/final}/final.stories.tsx (88%) rename src/course/{02-solutions/08-Provider => 02- lessons/02-Silver/Provider/final}/final.tsx (100%) rename src/course/02- lessons/{08-Provider => 02-Silver/Provider}/lesson.mdx (96%) rename src/course/02- lessons/{10-Compound => 02-Silver/RenderProps/exercise}/exercise.stories.tsx (87%) rename src/course/02- lessons/{03-RenderProps => 02-Silver/RenderProps/exercise}/exercise.tsx (91%) rename src/course/{02-solutions/08-Provider => 02- lessons/02-Silver/RenderProps/final}/final.stories.tsx (87%) rename src/course/{02-solutions/03-RenderProps => 02- lessons/02-Silver/RenderProps/final}/final.tsx (90%) rename src/course/02- lessons/{03-RenderProps => 02-Silver/RenderProps}/lesson.mdx (96%) rename src/course/02- lessons/{03-RenderProps => 02-Silver/StateReducer/exercise}/exercise.stories.tsx (87%) rename src/course/02- lessons/{09-StateReducer => 02-Silver/StateReducer/exercise}/exercise.tsx (100%) rename src/course/{02-solutions/05-Hooks => 02- lessons/02-Silver/StateReducer/final}/final.stories.tsx (87%) rename src/course/{02-solutions/09-StateReducer => 02- lessons/02-Silver/StateReducer/final}/final.tsx (97%) rename src/course/02- lessons/{09-StateReducer => 02-Silver/StateReducer}/lesson.mdx (97%) rename src/course/02- lessons/{07-HigherOrderComponents => 03-Gold/01-HigherOrderComponents/exercise}/exercise.stories.tsx (87%) rename src/course/02- lessons/{07-HigherOrderComponents => 03-Gold/01-HigherOrderComponents/exercise}/exercise.tsx (100%) rename src/course/02- lessons/{07-HigherOrderComponents => 03-Gold/01-HigherOrderComponents/exercise}/withPokemon.tsx (100%) rename src/course/{02-solutions/07-HigherOrderComponents => 02- lessons/03-Gold/01-HigherOrderComponents/final}/final.stories.tsx (86%) rename src/course/{02-solutions/07-HigherOrderComponents => 02- lessons/03-Gold/01-HigherOrderComponents/final}/final.tsx (95%) rename src/course/{02-solutions/07-HigherOrderComponents => 02- lessons/03-Gold/01-HigherOrderComponents/final}/withPokemon.tsx (94%) rename src/course/02- lessons/{07-HigherOrderComponents => 03-Gold/01-HigherOrderComponents}/lesson.mdx (96%) delete mode 100644 src/course/02-solutions/04-PresentationalAndContainer/mocks.ts delete mode 100644 src/course/02-solutions/05-Hooks/components.tsx delete mode 100644 src/course/02-solutions/10-Compound/final.stories.tsx delete mode 100644 src/course/02-solutions/11-Slots/icons/index.tsx diff --git a/.storybook/main.ts b/.storybook/main.ts index ed55f6b..3ade951 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,5 +1,6 @@ import type { StorybookConfig } from '@storybook/react-vite'; import { mergeConfig } from 'vite'; +import path from 'path'; const config: StorybookConfig = { stories: [ @@ -27,7 +28,12 @@ const config: StorybookConfig = { }, async viteFinal(baseConfig, { configType }) { return mergeConfig(baseConfig, { - ...(configType === 'PRODUCTION' ? { base: '/storybook/' } : {}) + ...(configType === 'PRODUCTION' ? { base: '/storybook/' } : {}), + resolve: { + alias: { + '@shared': path.resolve(__dirname, '../src', 'shared') + } + } }); } }; diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 2e15d5f..9ef9680 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -12,7 +12,12 @@ const preview: Preview = { code: Code } }, - storySort: ['Introduction', 'Lessons', 'Recipes'], + storySort: [ + 'Introduction', + 'Lessons', + ['πŸ₯‰ Bronze', 'πŸ₯ˆ Silver', 'πŸ₯‡ Gold'], + 'Recipes' + ], controls: { matchers: { color: /(background|color)$/i, diff --git a/package.json b/package.json index 10bdd62..40ed1d8 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives", "preview": "vite preview", "storybook": "storybook dev -p 6006", "build-storybook": "npm run build && storybook build -o dist/storybook", diff --git a/src/course/01-introduction/01-Welcome.mdx b/src/course/01-introduction/01-Welcome.mdx index fe55e20..87e2a82 100644 --- a/src/course/01-introduction/01-Welcome.mdx +++ b/src/course/01-introduction/01-Welcome.mdx @@ -34,22 +34,30 @@ I will be going in high detail on each of the lessons so if there are some holes ## Contents -Each lesson is broken down in an exercise file and a final file. The exercise file will have instructions in pseudo format to help guide you through the code snippets. Not to worry though, there will be videos to support you along the way. +Each lesson is broken down in an exercise file and a final file. The exercise file will have instructions in pseudo format to help guide you through the code snippets. ### Lessons -- 01 - [Conditionally rendering pattern](?path=/docs/lessons-01-conditional-rendering-pattern-01-lesson--docs) -- 02 - [Props combination pattern](?path=/docs/lessons-02-props-combination-pattern-01-lesson--docs) -- 03 - [Render props pattern](?path=/docs/lessons-03-render-props-pattern-01-lesson--docs) -- 04 - [Presentational and container components pattern](?path=/docs/lessons-04-presentational-container-pattern-01-lesson--docs) -- 05 - [React Hooks pattern](?path=/docs/lessons-05-hooks-pattern-01-lesson--docs) -- 06 - [Controlled component pattern](?path=/docs/lessons-06-controlled-components-pattern-01-lesson--docs) -- 07 - [Higher order component](?path=/docs/lessons-07-higher-order-components-pattern-01-lesson--docs) -- 08 - [The Provider pattern](?path=/docs/lessons-08-provider-pattern-01-lesson--docs) -- 09 - [The State Reducer pattern](?path=/docs/lessons-09-state-reducer-pattern-01-lesson--docs) -- 10 - [Compound components pattern](?path=/docs/lessons-10-compound-components-pattern-01-lesson--docs) -- 11 - [Slots pattern](?path=/docs/lessons-11-slots-01-lesson--docs) -- 12 - [Portals pattern](?path=/docs/lessons-12-portals-01-lesson--docs) +#### πŸ₯‰ Bronze + +- [Conditionally rendering pattern](?path=/docs/lessons-πŸ₯‰-bronze-conditional-rendering-pattern-01-lesson--docs) +- [Props combination pattern](?path=/docs/lessons-πŸ₯‰-bronze-props-combination-pattern-01-lesson--docs) +- [React Hooks pattern](?path=/docs/lessons-πŸ₯‰-bronze-hooks-pattern-01-lesson--docs) +- [Presentational and container components pattern](?path=/docs/lessons-πŸ₯‰-bronze-presentational-container-pattern-01-lesson--docs) +- [Slots pattern](?path=/docs/lessons-πŸ₯‰-bronze-slots-01-lesson--docs) + +#### πŸ₯ˆ Silver + +- [Compound components pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-compound-components-pattern-01-lesson--docs) +- [Controlled component pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-controlled-components-pattern-01-lesson--docs) +- [Render props pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-render-props-pattern-01-lesson--docs) +- [The Provider pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-provider-pattern-01-lesson--docs) +- [The State Reducer pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-state-reducer-pattern-01-lesson--docs) +- [Portals pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-portals-01-lesson--docs) + +#### πŸ₯‡ Gold + +- [Higher order component](?path=/docs/lessons-πŸ₯‡-gold-higher-order-components-pattern-01-lesson--docs) ## FAQs diff --git a/src/course/01-introduction/02-GettingStarted.mdx b/src/course/01-introduction/02-GettingStarted.mdx index 2e084b0..966de2a 100644 --- a/src/course/01-introduction/02-GettingStarted.mdx +++ b/src/course/01-introduction/02-GettingStarted.mdx @@ -4,7 +4,7 @@ import { Meta } from '@storybook/blocks'; # Getting Started -> Node version 18 required. +> Node version 18+ required. ## Installation diff --git a/src/course/01-introduction/03-LessonStructure.mdx b/src/course/01-introduction/03-LessonStructure.mdx index 8626b76..43fa999 100644 --- a/src/course/01-introduction/03-LessonStructure.mdx +++ b/src/course/01-introduction/03-LessonStructure.mdx @@ -4,7 +4,11 @@ import { Meta } from '@storybook/blocks'; # Lesson Structure -As you will have already noticed in the sidebar that there is a "Lessons" section. Each lesson will get slightly more and more complex as we go on so it eases us into the course. Each lesson will also contain an "exercise.(tsx)" file and a "final.(tsx)". +As you will have already noticed in the sidebar that there is a "Lessons" section. Each lesson sits within a Bronze/Silver/Gold tier folder which mirrors to the complexity of that pattern & we provide more challenging exercises. Each lesson will also contain an "exercise" folder and a "final" folder. + +## Storybook / Folder Structure + +As you can see the storybook sidebar mirrors the way the folder structure is within the repo. This is done so you can easily navigate to the files you are changing within the exercises. ## Exercise files @@ -60,6 +64,4 @@ const Component = () => { ## Final files -If you get stuck do not worry! Each lesson.mdx file will have a video going through it all and there will be a final.tsx file showing the final solution of each exercise. - -[Let's get started](?path=/docs/lessons-01-conditional-rendering-pattern-01-lesson--docs) +If you get stuck do not worry! Each will have a final folder in the lesson showing the final solution of each exercise. Head over to any of the lessons to get started with which patterns you wish to learn. diff --git a/src/course/02- lessons/01-Bronze/ConditionalRendering/exercise/exercise.stories.tsx b/src/course/02- lessons/01-Bronze/ConditionalRendering/exercise/exercise.stories.tsx new file mode 100644 index 0000000..b8777c9 --- /dev/null +++ b/src/course/02- lessons/01-Bronze/ConditionalRendering/exercise/exercise.stories.tsx @@ -0,0 +1,51 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { userEvent, within, expect } from '@storybook/test'; + +import { ComponentOne } from './exercise'; + +const meta: Meta = { + title: + 'Lessons/πŸ₯‰ Bronze/Conditional Rendering Pattern/02-Exercise', + component: ComponentOne +}; + +export default meta; +type Story = StoryObj; + +const username = 'John Doe'; + +/* + * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas + * to learn more about using the canvasElement to query the DOM + */ +export const Default: Story = { + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + + await userEvent.click( + canvas.getByRole('button', { name: 'Login' }) + ); + + await expect( + canvas.getByText(`Welcome ${username}`) + ).toBeInTheDocument(); + await expect( + canvas.queryByRole('button', { name: 'Login' }) + ).toBeNull(); + + await userEvent.click( + canvas.getByRole('button', { name: 'Logout' }) + ); + + await expect( + canvas.queryByText(`Welcome ${username}`) + ).toBeNull(); + await expect( + canvas.queryByRole('button', { name: 'Logout' }) + ).toBeNull(); + }, + args: { + username + } +}; diff --git a/src/course/02- lessons/01-ConditionalRendering/exercise.tsx b/src/course/02- lessons/01-Bronze/ConditionalRendering/exercise/exercise.tsx similarity index 92% rename from src/course/02- lessons/01-ConditionalRendering/exercise.tsx rename to src/course/02- lessons/01-Bronze/ConditionalRendering/exercise/exercise.tsx index 9fdbe6a..5bb0e63 100644 --- a/src/course/02- lessons/01-ConditionalRendering/exercise.tsx +++ b/src/course/02- lessons/01-Bronze/ConditionalRendering/exercise/exercise.tsx @@ -1,4 +1,4 @@ -import { Button } from '../../../shared/components/Button/Button.component'; +import { Button } from '@shared/components/Button/Button.component'; interface IComponentProps { username: string; diff --git a/src/course/02-solutions/01-ConditionalRendering/final.stories.tsx b/src/course/02- lessons/01-Bronze/ConditionalRendering/final/final.stories.tsx similarity index 51% rename from src/course/02-solutions/01-ConditionalRendering/final.stories.tsx rename to src/course/02- lessons/01-Bronze/ConditionalRendering/final/final.stories.tsx index a17bb30..7052c79 100644 --- a/src/course/02-solutions/01-ConditionalRendering/final.stories.tsx +++ b/src/course/02- lessons/01-Bronze/ConditionalRendering/final/final.stories.tsx @@ -1,11 +1,10 @@ import type { Meta, StoryObj } from '@storybook/react'; import { userEvent, within, expect } from '@storybook/test'; - import { ComponentOne } from './final'; const meta: Meta = { - title: 'Lessons/01 - Conditional Rendering Pattern/03-Final', + title: 'Lessons/πŸ₯‰ Bronze/Conditional Rendering Pattern/03-Final', component: ComponentOne }; @@ -22,15 +21,27 @@ export const Default: Story = { play: async ({ canvasElement }) => { const canvas = within(canvasElement); - await userEvent.click(canvas.getByRole('button', { name: 'Login' })); - - await expect(canvas.getByText(`Welcome ${username}`)).toBeInTheDocument(); - await expect(canvas.queryByRole('button', { name: 'Login' })).toBeNull(); - - await userEvent.click(canvas.getByRole('button', { name: 'Logout' })); - - await expect(canvas.queryByText(`Welcome ${username}`)).toBeNull(); - await expect(canvas.queryByRole('button', { name: 'Logout' })).toBeNull(); + await userEvent.click( + canvas.getByRole('button', { name: 'Login' }) + ); + + await expect( + canvas.getByText(`Welcome ${username}`) + ).toBeInTheDocument(); + await expect( + canvas.queryByRole('button', { name: 'Login' }) + ).toBeNull(); + + await userEvent.click( + canvas.getByRole('button', { name: 'Logout' }) + ); + + await expect( + canvas.queryByText(`Welcome ${username}`) + ).toBeNull(); + await expect( + canvas.queryByRole('button', { name: 'Logout' }) + ).toBeNull(); }, args: { username diff --git a/src/course/02-solutions/01-ConditionalRendering/final.tsx b/src/course/02- lessons/01-Bronze/ConditionalRendering/final/final.tsx similarity index 89% rename from src/course/02-solutions/01-ConditionalRendering/final.tsx rename to src/course/02- lessons/01-Bronze/ConditionalRendering/final/final.tsx index 0a9f76d..d2779ef 100644 --- a/src/course/02-solutions/01-ConditionalRendering/final.tsx +++ b/src/course/02- lessons/01-Bronze/ConditionalRendering/final/final.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { Button } from '../../../shared/components/Button/Button.component'; +import { Button } from '@shared/components/Button/Button.component'; interface IComponentProps { username: string; diff --git a/src/course/02- lessons/01-ConditionalRendering/lesson.mdx b/src/course/02- lessons/01-Bronze/ConditionalRendering/lesson.mdx similarity index 90% rename from src/course/02- lessons/01-ConditionalRendering/lesson.mdx rename to src/course/02- lessons/01-Bronze/ConditionalRendering/lesson.mdx index a27307e..ccecd36 100644 --- a/src/course/02- lessons/01-ConditionalRendering/lesson.mdx +++ b/src/course/02- lessons/01-Bronze/ConditionalRendering/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Conditional Rendering Pattern @@ -86,7 +86,7 @@ const Component = () => { ## Exercise -In the first exercise we are going to look into building a login and logout toggle which will render a username when they have logged in. Go to the exercise.tsx inside the 01-ConditionalRendering folder and start the exercise. Once completed, the Tests will show as passed in the storybook "Interactions" addon section. +In the first exercise we are going to look into building a login and logout toggle which will render a username when they have logged in. Go to the exercise.tsx inside the ConditionalRendering folder and start the exercise. Once completed, the Tests will show as passed in the storybook "Interactions" addon section. ## Feedback diff --git a/src/course/02- lessons/05-Hooks/components.tsx b/src/course/02- lessons/01-Bronze/Hooks/components.tsx similarity index 71% rename from src/course/02- lessons/05-Hooks/components.tsx rename to src/course/02- lessons/01-Bronze/Hooks/components.tsx index 2adee81..63591b5 100644 --- a/src/course/02- lessons/05-Hooks/components.tsx +++ b/src/course/02- lessons/01-Bronze/Hooks/components.tsx @@ -1,6 +1,6 @@ -import { Input } from '../../../shared/components/Input/Input.component'; -import { Label } from '../../../shared/components/Label/Label.component'; -import { ErrorMessage } from '../../../shared/components/ErrorMessage/ErrorMessage.component'; +import { Input } from '@shared/components/Input/Input.component'; +import { Label } from '@shared/components/Label/Label.component'; +import { ErrorMessage } from '@shared/components/ErrorMessage/ErrorMessage.component'; import { HTMLAttributes } from 'react'; export interface ITextFieldProps { diff --git a/src/course/02- lessons/08-Provider/exercise.stories.tsx b/src/course/02- lessons/01-Bronze/Hooks/exercise/exercise.stories.tsx similarity index 88% rename from src/course/02- lessons/08-Provider/exercise.stories.tsx rename to src/course/02- lessons/01-Bronze/Hooks/exercise/exercise.stories.tsx index 6feb89c..2407fb0 100644 --- a/src/course/02- lessons/08-Provider/exercise.stories.tsx +++ b/src/course/02- lessons/01-Bronze/Hooks/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/08 - Provider Pattern/02-Exercise', + title: 'Lessons/πŸ₯‰ Bronze/Hooks Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/05-Hooks/exercise.tsx b/src/course/02- lessons/01-Bronze/Hooks/exercise/exercise.tsx similarity index 97% rename from src/course/02- lessons/05-Hooks/exercise.tsx rename to src/course/02- lessons/01-Bronze/Hooks/exercise/exercise.tsx index 7191929..875f1bb 100644 --- a/src/course/02- lessons/05-Hooks/exercise.tsx +++ b/src/course/02- lessons/01-Bronze/Hooks/exercise/exercise.tsx @@ -1,5 +1,5 @@ import { ChangeEvent, useState } from 'react'; -import { ITextFieldProps, TextFieldComponent } from './components'; +import { ITextFieldProps, TextFieldComponent } from '../components'; /* * Observations diff --git a/src/course/02-solutions/03-RenderProps/final.stories.tsx b/src/course/02- lessons/01-Bronze/Hooks/final/final.stories.tsx similarity index 88% rename from src/course/02-solutions/03-RenderProps/final.stories.tsx rename to src/course/02- lessons/01-Bronze/Hooks/final/final.stories.tsx index 38c16c2..bc3c325 100644 --- a/src/course/02-solutions/03-RenderProps/final.stories.tsx +++ b/src/course/02- lessons/01-Bronze/Hooks/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/03 - Render Props Pattern/03-Final', + title: 'Lessons/πŸ₯‰ Bronze/Hooks Pattern/03-Final', component: Final }; diff --git a/src/course/02-solutions/05-Hooks/final.tsx b/src/course/02- lessons/01-Bronze/Hooks/final/final.tsx similarity index 96% rename from src/course/02-solutions/05-Hooks/final.tsx rename to src/course/02- lessons/01-Bronze/Hooks/final/final.tsx index 95f7cad..ec340b2 100644 --- a/src/course/02-solutions/05-Hooks/final.tsx +++ b/src/course/02- lessons/01-Bronze/Hooks/final/final.tsx @@ -1,5 +1,5 @@ import { ChangeEvent, useState } from 'react'; -import { TextFieldComponent } from './components'; +import { TextFieldComponent } from '../components'; interface IFieldProps { name: string; diff --git a/src/course/02- lessons/05-Hooks/lesson.mdx b/src/course/02- lessons/01-Bronze/Hooks/lesson.mdx similarity index 98% rename from src/course/02- lessons/05-Hooks/lesson.mdx rename to src/course/02- lessons/01-Bronze/Hooks/lesson.mdx index a55afb9..6ab9443 100644 --- a/src/course/02- lessons/05-Hooks/lesson.mdx +++ b/src/course/02- lessons/01-Bronze/Hooks/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Hooks Pattern diff --git a/src/course/02- lessons/04-PresentationalAndContainer/exercise.stories.tsx b/src/course/02- lessons/01-Bronze/PresentationalAndContainer/exercise/exercise.stories.tsx similarity index 86% rename from src/course/02- lessons/04-PresentationalAndContainer/exercise.stories.tsx rename to src/course/02- lessons/01-Bronze/PresentationalAndContainer/exercise/exercise.stories.tsx index d3892a6..0f004ef 100644 --- a/src/course/02- lessons/04-PresentationalAndContainer/exercise.stories.tsx +++ b/src/course/02- lessons/01-Bronze/PresentationalAndContainer/exercise/exercise.stories.tsx @@ -4,7 +4,7 @@ import { BrandPageOne, BrandPageTwo } from './exercise'; const meta: Meta = { title: - 'Lessons/04 - Presentational & Container Pattern/02-Exercise', + 'Lessons/πŸ₯‰ Bronze/Presentational & Container Pattern/02-Exercise', component: BrandPageOne }; diff --git a/src/course/02- lessons/04-PresentationalAndContainer/exercise.tsx b/src/course/02- lessons/01-Bronze/PresentationalAndContainer/exercise/exercise.tsx similarity index 93% rename from src/course/02- lessons/04-PresentationalAndContainer/exercise.tsx rename to src/course/02- lessons/01-Bronze/PresentationalAndContainer/exercise/exercise.tsx index 215ef12..9b199da 100644 --- a/src/course/02- lessons/04-PresentationalAndContainer/exercise.tsx +++ b/src/course/02- lessons/01-Bronze/PresentationalAndContainer/exercise/exercise.tsx @@ -1,12 +1,12 @@ import { useEffect, useState } from 'react'; -import { ErrorMessage } from '../../../shared/components/ErrorMessage/ErrorMessage.component'; +import { ErrorMessage } from '@shared/components/ErrorMessage/ErrorMessage.component'; import { ICheckoutData, useBrandOnePayment, useCheckout -} from './mocks'; -import { Skeleton } from '../../../shared/components/Skeleton/Skeleton.component'; -import { Button } from '../../../shared/components/Button/Button.component'; +} from '../mocks'; +import { Skeleton } from '@shared/components/Skeleton/Skeleton.component'; +import { Button } from '@shared/components/Button/Button.component'; interface IPaymentTemplate { hasPaymentFailed: boolean; diff --git a/src/course/02-solutions/04-PresentationalAndContainer/final.stories.tsx b/src/course/02- lessons/01-Bronze/PresentationalAndContainer/final/final.stories.tsx similarity index 85% rename from src/course/02-solutions/04-PresentationalAndContainer/final.stories.tsx rename to src/course/02- lessons/01-Bronze/PresentationalAndContainer/final/final.stories.tsx index a6bd4a5..448e8fe 100644 --- a/src/course/02-solutions/04-PresentationalAndContainer/final.stories.tsx +++ b/src/course/02- lessons/01-Bronze/PresentationalAndContainer/final/final.stories.tsx @@ -3,7 +3,8 @@ import type { Meta, StoryObj } from '@storybook/react'; import { BrandPageOne, BrandPageTwo } from './final'; const meta: Meta = { - title: 'Lessons/04 - Presentational & Container Pattern/03-Final', + title: + 'Lessons/πŸ₯‰ Bronze/Presentational & Container Pattern/03-Final', component: BrandPageOne }; diff --git a/src/course/02-solutions/04-PresentationalAndContainer/final.tsx b/src/course/02- lessons/01-Bronze/PresentationalAndContainer/final/final.tsx similarity index 93% rename from src/course/02-solutions/04-PresentationalAndContainer/final.tsx rename to src/course/02- lessons/01-Bronze/PresentationalAndContainer/final/final.tsx index 028dc5e..e539017 100644 --- a/src/course/02-solutions/04-PresentationalAndContainer/final.tsx +++ b/src/course/02- lessons/01-Bronze/PresentationalAndContainer/final/final.tsx @@ -1,13 +1,13 @@ import { useEffect, useState } from 'react'; -import { ErrorMessage } from '../../../shared/components/ErrorMessage/ErrorMessage.component'; +import { ErrorMessage } from '@shared/components/ErrorMessage/ErrorMessage.component'; import { useBrandOnePayment, useCheckout, useBrandTwoPayment, ICheckoutData -} from './mocks'; -import { Button } from '../../../shared/components/Button/Button.component'; -import { Skeleton } from '../../../shared/components/Skeleton/Skeleton.component'; +} from '../mocks'; +import { Button } from '@shared/components/Button/Button.component'; +import { Skeleton } from '@shared/components/Skeleton/Skeleton.component'; interface IPaymentTemplate { hasPaymentFailed: boolean; diff --git a/src/course/02- lessons/04-PresentationalAndContainer/lesson.mdx b/src/course/02- lessons/01-Bronze/PresentationalAndContainer/lesson.mdx similarity index 98% rename from src/course/02- lessons/04-PresentationalAndContainer/lesson.mdx rename to src/course/02- lessons/01-Bronze/PresentationalAndContainer/lesson.mdx index b784a02..080b3ae 100644 --- a/src/course/02- lessons/04-PresentationalAndContainer/lesson.mdx +++ b/src/course/02- lessons/01-Bronze/PresentationalAndContainer/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Presentational & Container Pattern diff --git a/src/course/02- lessons/04-PresentationalAndContainer/mocks.ts b/src/course/02- lessons/01-Bronze/PresentationalAndContainer/mocks.ts similarity index 100% rename from src/course/02- lessons/04-PresentationalAndContainer/mocks.ts rename to src/course/02- lessons/01-Bronze/PresentationalAndContainer/mocks.ts diff --git a/src/course/02- lessons/02-PropsCombination/exercise.stories.tsx b/src/course/02- lessons/01-Bronze/PropsCombination/exercise/exercise.stories.tsx similarity index 94% rename from src/course/02- lessons/02-PropsCombination/exercise.stories.tsx rename to src/course/02- lessons/01-Bronze/PropsCombination/exercise/exercise.stories.tsx index 0b6a2f8..3a85de5 100644 --- a/src/course/02- lessons/02-PropsCombination/exercise.stories.tsx +++ b/src/course/02- lessons/01-Bronze/PropsCombination/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/02 - Props Combination Pattern/02-Exercise', + title: 'Lessons/πŸ₯‰ Bronze/Props Combination Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/02-PropsCombination/exercise.tsx b/src/course/02- lessons/01-Bronze/PropsCombination/exercise/exercise.tsx similarity index 100% rename from src/course/02- lessons/02-PropsCombination/exercise.tsx rename to src/course/02- lessons/01-Bronze/PropsCombination/exercise/exercise.tsx diff --git a/src/course/02-solutions/02-PropsCombination/final.stories.tsx b/src/course/02- lessons/01-Bronze/PropsCombination/final/final.stories.tsx similarity index 94% rename from src/course/02-solutions/02-PropsCombination/final.stories.tsx rename to src/course/02- lessons/01-Bronze/PropsCombination/final/final.stories.tsx index 6b5a5fe..fe71bb7 100644 --- a/src/course/02-solutions/02-PropsCombination/final.stories.tsx +++ b/src/course/02- lessons/01-Bronze/PropsCombination/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/02 - Props Combination Pattern/03-Final', + title: 'Lessons/πŸ₯‰ Bronze/Props Combination Pattern/03-Final', component: Final }; diff --git a/src/course/02-solutions/02-PropsCombination/final.tsx b/src/course/02- lessons/01-Bronze/PropsCombination/final/final.tsx similarity index 100% rename from src/course/02-solutions/02-PropsCombination/final.tsx rename to src/course/02- lessons/01-Bronze/PropsCombination/final/final.tsx diff --git a/src/course/02- lessons/02-PropsCombination/lesson.mdx b/src/course/02- lessons/01-Bronze/PropsCombination/lesson.mdx similarity index 96% rename from src/course/02- lessons/02-PropsCombination/lesson.mdx rename to src/course/02- lessons/01-Bronze/PropsCombination/lesson.mdx index 475e56a..2115d3c 100644 --- a/src/course/02- lessons/02-PropsCombination/lesson.mdx +++ b/src/course/02- lessons/01-Bronze/PropsCombination/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Props Combination Pattern diff --git a/src/course/02- lessons/11-Slots/exercise.stories.tsx b/src/course/02- lessons/01-Bronze/Slots/exercise/exercise.stories.tsx similarity index 90% rename from src/course/02- lessons/11-Slots/exercise.stories.tsx rename to src/course/02- lessons/01-Bronze/Slots/exercise/exercise.stories.tsx index c3521e5..a40b57b 100644 --- a/src/course/02- lessons/11-Slots/exercise.stories.tsx +++ b/src/course/02- lessons/01-Bronze/Slots/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/11 - Slots/02-Exercise', + title: 'Lessons/πŸ₯‰ Bronze/Slots/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/11-Slots/exercise.tsx b/src/course/02- lessons/01-Bronze/Slots/exercise/exercise.tsx similarity index 100% rename from src/course/02- lessons/11-Slots/exercise.tsx rename to src/course/02- lessons/01-Bronze/Slots/exercise/exercise.tsx diff --git a/src/course/02-solutions/11-Slots/final.stories.tsx b/src/course/02- lessons/01-Bronze/Slots/final/final.stories.tsx similarity index 90% rename from src/course/02-solutions/11-Slots/final.stories.tsx rename to src/course/02- lessons/01-Bronze/Slots/final/final.stories.tsx index dc71714..8fb0fda 100644 --- a/src/course/02-solutions/11-Slots/final.stories.tsx +++ b/src/course/02- lessons/01-Bronze/Slots/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/11 - Slots/03-Final', + title: 'Lessons/πŸ₯‰ Bronze/Slots/03-Final', component: Final }; diff --git a/src/course/02-solutions/11-Slots/final.tsx b/src/course/02- lessons/01-Bronze/Slots/final/final.tsx similarity index 96% rename from src/course/02-solutions/11-Slots/final.tsx rename to src/course/02- lessons/01-Bronze/Slots/final/final.tsx index fb91eb8..b34f17c 100644 --- a/src/course/02-solutions/11-Slots/final.tsx +++ b/src/course/02- lessons/01-Bronze/Slots/final/final.tsx @@ -1,6 +1,6 @@ import classNames from 'classnames'; import { HTMLAttributes } from 'react'; -import { IconOne, IconTwo } from './icons'; +import { IconOne, IconTwo } from '../icons'; interface IButton extends HTMLAttributes { className?: string; diff --git a/src/course/02- lessons/11-Slots/icons/index.tsx b/src/course/02- lessons/01-Bronze/Slots/icons/index.tsx similarity index 100% rename from src/course/02- lessons/11-Slots/icons/index.tsx rename to src/course/02- lessons/01-Bronze/Slots/icons/index.tsx diff --git a/src/course/02- lessons/11-Slots/lesson.mdx b/src/course/02- lessons/01-Bronze/Slots/lesson.mdx similarity index 97% rename from src/course/02- lessons/11-Slots/lesson.mdx rename to src/course/02- lessons/01-Bronze/Slots/lesson.mdx index 2093db8..3538912 100644 --- a/src/course/02- lessons/11-Slots/lesson.mdx +++ b/src/course/02- lessons/01-Bronze/Slots/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Slots Pattern diff --git a/src/course/02- lessons/01-ConditionalRendering/exercise.stories.tsx b/src/course/02- lessons/01-ConditionalRendering/exercise.stories.tsx deleted file mode 100644 index 5c66860..0000000 --- a/src/course/02- lessons/01-ConditionalRendering/exercise.stories.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react"; - -import { userEvent, within, expect } from "@storybook/test"; - -import { ComponentOne } from "./exercise"; - -const meta: Meta = { - title: "Lessons/01 - Conditional Rendering Pattern/02-Exercise", - component: ComponentOne, -}; - -export default meta; -type Story = StoryObj; - -const username = "John Doe"; - -/* - * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas - * to learn more about using the canvasElement to query the DOM - */ -export const Default: Story = { - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - - await userEvent.click(canvas.getByRole("button", { name: "Login" })); - - await expect(canvas.getByText(`Welcome ${username}`)).toBeInTheDocument(); - await expect(canvas.queryByRole("button", { name: "Login" })).toBeNull(); - - await userEvent.click(canvas.getByRole("button", { name: "Logout" })); - - await expect(canvas.queryByText(`Welcome ${username}`)).toBeNull(); - await expect(canvas.queryByRole("button", { name: "Logout" })).toBeNull(); - }, - args: { - username, - }, -}; diff --git a/src/course/02- lessons/10-Compound/components/Accordion.tsx b/src/course/02- lessons/02-Silver/Compound/exercise/components/Accordion.tsx similarity index 100% rename from src/course/02- lessons/10-Compound/components/Accordion.tsx rename to src/course/02- lessons/02-Silver/Compound/exercise/components/Accordion.tsx diff --git a/src/course/02- lessons/10-Compound/components/Accoridon.module.css b/src/course/02- lessons/02-Silver/Compound/exercise/components/Accoridon.module.css similarity index 100% rename from src/course/02- lessons/10-Compound/components/Accoridon.module.css rename to src/course/02- lessons/02-Silver/Compound/exercise/components/Accoridon.module.css diff --git a/src/course/02- lessons/10-Compound/components/ChevronDown.tsx b/src/course/02- lessons/02-Silver/Compound/exercise/components/ChevronDown.tsx similarity index 100% rename from src/course/02- lessons/10-Compound/components/ChevronDown.tsx rename to src/course/02- lessons/02-Silver/Compound/exercise/components/ChevronDown.tsx diff --git a/src/course/02- lessons/06-Controlled/exercise.stories.tsx b/src/course/02- lessons/02-Silver/Compound/exercise/exercise.stories.tsx similarity index 86% rename from src/course/02- lessons/06-Controlled/exercise.stories.tsx rename to src/course/02- lessons/02-Silver/Compound/exercise/exercise.stories.tsx index 57b9197..b35e34d 100644 --- a/src/course/02- lessons/06-Controlled/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/Compound/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/06 - Controlled Components Pattern/02-Exercise', + title: 'Lessons/πŸ₯ˆ Sliver/Compound Components Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/10-Compound/exercise.tsx b/src/course/02- lessons/02-Silver/Compound/exercise/exercise.tsx similarity index 100% rename from src/course/02- lessons/10-Compound/exercise.tsx rename to src/course/02- lessons/02-Silver/Compound/exercise/exercise.tsx diff --git a/src/course/02-solutions/10-Compound/components/Accordion.tsx b/src/course/02- lessons/02-Silver/Compound/final/components/Accordion.tsx similarity index 100% rename from src/course/02-solutions/10-Compound/components/Accordion.tsx rename to src/course/02- lessons/02-Silver/Compound/final/components/Accordion.tsx diff --git a/src/course/02-solutions/10-Compound/components/Accoridon.module.css b/src/course/02- lessons/02-Silver/Compound/final/components/Accoridon.module.css similarity index 100% rename from src/course/02-solutions/10-Compound/components/Accoridon.module.css rename to src/course/02- lessons/02-Silver/Compound/final/components/Accoridon.module.css diff --git a/src/course/02-solutions/10-Compound/components/ChevronDown.tsx b/src/course/02- lessons/02-Silver/Compound/final/components/ChevronDown.tsx similarity index 100% rename from src/course/02-solutions/10-Compound/components/ChevronDown.tsx rename to src/course/02- lessons/02-Silver/Compound/final/components/ChevronDown.tsx diff --git a/src/course/02-solutions/06-Controlled/final.stories.tsx b/src/course/02- lessons/02-Silver/Compound/final/final.stories.tsx similarity index 86% rename from src/course/02-solutions/06-Controlled/final.stories.tsx rename to src/course/02- lessons/02-Silver/Compound/final/final.stories.tsx index 830039c..d09a9cb 100644 --- a/src/course/02-solutions/06-Controlled/final.stories.tsx +++ b/src/course/02- lessons/02-Silver/Compound/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/06 - Controlled Components Pattern/03-Final', + title: 'Lessons/πŸ₯ˆ Sliver/Compound Components Pattern/03-Final', component: Final }; diff --git a/src/course/02-solutions/10-Compound/final.tsx b/src/course/02- lessons/02-Silver/Compound/final/final.tsx similarity index 100% rename from src/course/02-solutions/10-Compound/final.tsx rename to src/course/02- lessons/02-Silver/Compound/final/final.tsx diff --git a/src/course/02- lessons/10-Compound/lesson.mdx b/src/course/02- lessons/02-Silver/Compound/lesson.mdx similarity index 96% rename from src/course/02- lessons/10-Compound/lesson.mdx rename to src/course/02- lessons/02-Silver/Compound/lesson.mdx index 66b3236..9751a69 100644 --- a/src/course/02- lessons/10-Compound/lesson.mdx +++ b/src/course/02- lessons/02-Silver/Compound/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Compound Components Pattern diff --git a/src/course/02- lessons/05-Hooks/exercise.stories.tsx b/src/course/02- lessons/02-Silver/Controlled/exercise/exercise.stories.tsx similarity index 85% rename from src/course/02- lessons/05-Hooks/exercise.stories.tsx rename to src/course/02- lessons/02-Silver/Controlled/exercise/exercise.stories.tsx index 28c98ec..1bda094 100644 --- a/src/course/02- lessons/05-Hooks/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/Controlled/exercise/exercise.stories.tsx @@ -3,7 +3,8 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/05 - Hooks Pattern/02-Exercise', + title: + 'Lessons/πŸ₯ˆ Sliver/Controlled Components Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/06-Controlled/exercise.tsx b/src/course/02- lessons/02-Silver/Controlled/exercise/exercise.tsx similarity index 98% rename from src/course/02- lessons/06-Controlled/exercise.tsx rename to src/course/02- lessons/02-Silver/Controlled/exercise/exercise.tsx index 5d723eb..d3878c7 100644 --- a/src/course/02- lessons/06-Controlled/exercise.tsx +++ b/src/course/02- lessons/02-Silver/Controlled/exercise/exercise.tsx @@ -5,7 +5,7 @@ import classNames from 'classnames'; // eslint-disable-next-line @typescript-eslint/no-unused-vars import { useEffect, useRef, useState } from 'react'; import FocusLock from 'react-focus-lock'; -import { Button } from '../../../shared/components/Button/Button.component'; +import { Button } from '@shared/components/Button/Button.component'; interface IModal { isVisible: boolean; diff --git a/src/course/02- lessons/02-Silver/Controlled/final/final.stories.tsx b/src/course/02- lessons/02-Silver/Controlled/final/final.stories.tsx new file mode 100644 index 0000000..61763d8 --- /dev/null +++ b/src/course/02- lessons/02-Silver/Controlled/final/final.stories.tsx @@ -0,0 +1,20 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Final } from './final'; + +const meta: Meta = { + title: 'Lessons/πŸ₯ˆ Sliver/Controlled Components Pattern/03-Final', + component: Final +}; + +export default meta; +type Story = StoryObj; + +/* + * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas + * to learn more about using the canvasElement to query the DOM + */ +export const Default: Story = { + play: async () => {}, + args: {} +}; diff --git a/src/course/02-solutions/06-Controlled/final.tsx b/src/course/02- lessons/02-Silver/Controlled/final/final.tsx similarity index 96% rename from src/course/02-solutions/06-Controlled/final.tsx rename to src/course/02- lessons/02-Silver/Controlled/final/final.tsx index b4bbb8e..0976052 100644 --- a/src/course/02-solutions/06-Controlled/final.tsx +++ b/src/course/02- lessons/02-Silver/Controlled/final/final.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames'; import { useEffect, useRef, useState } from 'react'; import FocusLock from 'react-focus-lock'; -import { Button } from '../../../shared/components/Button/Button.component'; +import { Button } from '@shared/components/Button/Button.component'; interface IModal { isVisible: boolean; diff --git a/src/course/02- lessons/06-Controlled/lesson.mdx b/src/course/02- lessons/02-Silver/Controlled/lesson.mdx similarity index 96% rename from src/course/02- lessons/06-Controlled/lesson.mdx rename to src/course/02- lessons/02-Silver/Controlled/lesson.mdx index 1b2b099..f238cf0 100644 --- a/src/course/02- lessons/06-Controlled/lesson.mdx +++ b/src/course/02- lessons/02-Silver/Controlled/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Controlled Components Pattern diff --git a/src/course/02- lessons/12-Portals/components/modal.tsx b/src/course/02- lessons/02-Silver/Portals/exercise/components/modal.tsx similarity index 96% rename from src/course/02- lessons/12-Portals/components/modal.tsx rename to src/course/02- lessons/02-Silver/Portals/exercise/components/modal.tsx index 749bbd0..e209c37 100644 --- a/src/course/02- lessons/12-Portals/components/modal.tsx +++ b/src/course/02- lessons/02-Silver/Portals/exercise/components/modal.tsx @@ -2,7 +2,7 @@ import classNames from 'classnames'; import { useEffect, useRef } from 'react'; // πŸ‘¨πŸ»β€πŸ’» 1B - import { createPortal } from 'react-dom'; import FocusLock from 'react-focus-lock'; -import { Button } from '../../../../shared/components/Button/Button.component'; +import { Button } from '@shared/components/Button/Button.component'; interface IModal { isVisible: boolean; diff --git a/src/course/02- lessons/12-Portals/exercise.stories.tsx b/src/course/02- lessons/02-Silver/Portals/exercise/exercise.stories.tsx similarity index 89% rename from src/course/02- lessons/12-Portals/exercise.stories.tsx rename to src/course/02- lessons/02-Silver/Portals/exercise/exercise.stories.tsx index 63d4c26..f032f5d 100644 --- a/src/course/02- lessons/12-Portals/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/Portals/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/12 - Portals/02-Exercise', + title: 'Lessons/πŸ₯ˆ Sliver/Portals/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/12-Portals/exercise.tsx b/src/course/02- lessons/02-Silver/Portals/exercise/exercise.tsx similarity index 96% rename from src/course/02- lessons/12-Portals/exercise.tsx rename to src/course/02- lessons/02-Silver/Portals/exercise/exercise.tsx index 7158c39..9e87a08 100644 --- a/src/course/02- lessons/12-Portals/exercise.tsx +++ b/src/course/02- lessons/02-Silver/Portals/exercise/exercise.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { Modal } from './components/modal'; -import { Button } from '../../../shared/components/Button/Button.component'; +import { Button } from '@shared/components/Button/Button.component'; // πŸ‘¨πŸ»β€πŸ’» 1A - have a look at the current implementation of the modal and then go to components/modal.tsx diff --git a/src/course/02-solutions/12-Portals/components/modal.tsx b/src/course/02- lessons/02-Silver/Portals/final/components/modal.tsx similarity index 95% rename from src/course/02-solutions/12-Portals/components/modal.tsx rename to src/course/02- lessons/02-Silver/Portals/final/components/modal.tsx index e25f422..bb42cff 100644 --- a/src/course/02-solutions/12-Portals/components/modal.tsx +++ b/src/course/02- lessons/02-Silver/Portals/final/components/modal.tsx @@ -2,7 +2,7 @@ import classNames from 'classnames'; import { useEffect, useRef } from 'react'; import { createPortal } from 'react-dom'; import FocusLock from 'react-focus-lock'; -import { Button } from '../../../../shared/components/Button/Button.component'; +import { Button } from '@shared/components/Button/Button.component'; interface IModal { isVisible: boolean; diff --git a/src/course/02-solutions/12-Portals/final.stories.tsx b/src/course/02- lessons/02-Silver/Portals/final/final.stories.tsx similarity index 89% rename from src/course/02-solutions/12-Portals/final.stories.tsx rename to src/course/02- lessons/02-Silver/Portals/final/final.stories.tsx index 55f1e75..7bf7e01 100644 --- a/src/course/02-solutions/12-Portals/final.stories.tsx +++ b/src/course/02- lessons/02-Silver/Portals/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/12 - Portals/03-Final', + title: 'Lessons/πŸ₯ˆ Sliver/Portals/03-Final', component: Final }; diff --git a/src/course/02-solutions/12-Portals/final.tsx b/src/course/02- lessons/02-Silver/Portals/final/final.tsx similarity index 96% rename from src/course/02-solutions/12-Portals/final.tsx rename to src/course/02- lessons/02-Silver/Portals/final/final.tsx index 3504ff6..04c5305 100644 --- a/src/course/02-solutions/12-Portals/final.tsx +++ b/src/course/02- lessons/02-Silver/Portals/final/final.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { Modal } from './components/modal'; -import { Button } from '../../../shared/components/Button/Button.component'; +import { Button } from '@shared/components/Button/Button.component'; export const Final = () => { const [isVisible, setIsVisible] = useState(false); diff --git a/src/course/02- lessons/12-Portals/lesson.mdx b/src/course/02- lessons/02-Silver/Portals/lesson.mdx similarity index 96% rename from src/course/02- lessons/12-Portals/lesson.mdx rename to src/course/02- lessons/02-Silver/Portals/lesson.mdx index 8b7a9f4..517a6d2 100644 --- a/src/course/02- lessons/12-Portals/lesson.mdx +++ b/src/course/02- lessons/02-Silver/Portals/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Portals Pattern diff --git a/src/course/02- lessons/08-Provider/Provider.tsx b/src/course/02- lessons/02-Silver/Provider/exercise/Provider.tsx similarity index 100% rename from src/course/02- lessons/08-Provider/Provider.tsx rename to src/course/02- lessons/02-Silver/Provider/exercise/Provider.tsx diff --git a/src/course/02- lessons/09-StateReducer/exercise.stories.tsx b/src/course/02- lessons/02-Silver/Provider/exercise/exercise.stories.tsx similarity index 88% rename from src/course/02- lessons/09-StateReducer/exercise.stories.tsx rename to src/course/02- lessons/02-Silver/Provider/exercise/exercise.stories.tsx index 17ae5bb..2775324 100644 --- a/src/course/02- lessons/09-StateReducer/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/Provider/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/09 - State Reducer Pattern/02-Exercise', + title: 'Lessons/πŸ₯ˆ Sliver/Provider Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/08-Provider/exercise.tsx b/src/course/02- lessons/02-Silver/Provider/exercise/exercise.tsx similarity index 100% rename from src/course/02- lessons/08-Provider/exercise.tsx rename to src/course/02- lessons/02-Silver/Provider/exercise/exercise.tsx diff --git a/src/course/02-solutions/08-Provider/Provider.tsx b/src/course/02- lessons/02-Silver/Provider/final/Provider.tsx similarity index 95% rename from src/course/02-solutions/08-Provider/Provider.tsx rename to src/course/02- lessons/02-Silver/Provider/final/Provider.tsx index 6f0bdb8..82dff67 100644 --- a/src/course/02-solutions/08-Provider/Provider.tsx +++ b/src/course/02- lessons/02-Silver/Provider/final/Provider.tsx @@ -2,7 +2,7 @@ import { createContext, useContext, useMemo, useState } from 'react'; import { IPokemonManagerState, PokemonManager -} from '../../../shared/modules/PokemonManager/PokemonManager'; +} from '@shared/modules/PokemonManager/PokemonManager'; export interface IPokemonProviderState extends IPokemonManagerState { fetchPokemons: (total: number) => Promise; diff --git a/src/course/02-solutions/09-StateReducer/final.stories.tsx b/src/course/02- lessons/02-Silver/Provider/final/final.stories.tsx similarity index 88% rename from src/course/02-solutions/09-StateReducer/final.stories.tsx rename to src/course/02- lessons/02-Silver/Provider/final/final.stories.tsx index 493f022..dfc29b9 100644 --- a/src/course/02-solutions/09-StateReducer/final.stories.tsx +++ b/src/course/02- lessons/02-Silver/Provider/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/09 - State Reducer Pattern/03-Final', + title: 'Lessons/πŸ₯ˆ Sliver/Provider Pattern/03-Final', component: Final }; diff --git a/src/course/02-solutions/08-Provider/final.tsx b/src/course/02- lessons/02-Silver/Provider/final/final.tsx similarity index 100% rename from src/course/02-solutions/08-Provider/final.tsx rename to src/course/02- lessons/02-Silver/Provider/final/final.tsx diff --git a/src/course/02- lessons/08-Provider/lesson.mdx b/src/course/02- lessons/02-Silver/Provider/lesson.mdx similarity index 96% rename from src/course/02- lessons/08-Provider/lesson.mdx rename to src/course/02- lessons/02-Silver/Provider/lesson.mdx index ffa9838..032ca68 100644 --- a/src/course/02- lessons/08-Provider/lesson.mdx +++ b/src/course/02- lessons/02-Silver/Provider/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Provider Pattern diff --git a/src/course/02- lessons/10-Compound/exercise.stories.tsx b/src/course/02- lessons/02-Silver/RenderProps/exercise/exercise.stories.tsx similarity index 87% rename from src/course/02- lessons/10-Compound/exercise.stories.tsx rename to src/course/02- lessons/02-Silver/RenderProps/exercise/exercise.stories.tsx index ac0daa2..4ae95da 100644 --- a/src/course/02- lessons/10-Compound/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/RenderProps/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/10 - Compound Components Pattern/02-Exercise', + title: 'Lessons/πŸ₯ˆ Sliver/Render Props Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/03-RenderProps/exercise.tsx b/src/course/02- lessons/02-Silver/RenderProps/exercise/exercise.tsx similarity index 91% rename from src/course/02- lessons/03-RenderProps/exercise.tsx rename to src/course/02- lessons/02-Silver/RenderProps/exercise/exercise.tsx index 5e07985..62f783e 100644 --- a/src/course/02- lessons/03-RenderProps/exercise.tsx +++ b/src/course/02- lessons/02-Silver/RenderProps/exercise/exercise.tsx @@ -1,7 +1,7 @@ import { ChangeEvent, useState } from 'react'; -import { Input } from '../../../shared/components/Input/Input.component'; -import { Label } from '../../../shared/components/Label/Label.component'; -import { ErrorMessage } from '../../../shared/components/ErrorMessage/ErrorMessage.component'; +import { Input } from '@shared/components/Input/Input.component'; +import { Label } from '@shared/components/Label/Label.component'; +import { ErrorMessage } from '@shared/components/ErrorMessage/ErrorMessage.component'; export interface ITextInputFieldProps { name: string; diff --git a/src/course/02-solutions/08-Provider/final.stories.tsx b/src/course/02- lessons/02-Silver/RenderProps/final/final.stories.tsx similarity index 87% rename from src/course/02-solutions/08-Provider/final.stories.tsx rename to src/course/02- lessons/02-Silver/RenderProps/final/final.stories.tsx index e9d0334..d19b771 100644 --- a/src/course/02-solutions/08-Provider/final.stories.tsx +++ b/src/course/02- lessons/02-Silver/RenderProps/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/08 - Provider Pattern/03-Final', + title: 'Lessons/πŸ₯ˆ Sliver/Render Props Pattern/03-Final', component: Final }; diff --git a/src/course/02-solutions/03-RenderProps/final.tsx b/src/course/02- lessons/02-Silver/RenderProps/final/final.tsx similarity index 90% rename from src/course/02-solutions/03-RenderProps/final.tsx rename to src/course/02- lessons/02-Silver/RenderProps/final/final.tsx index f453323..e22879c 100644 --- a/src/course/02-solutions/03-RenderProps/final.tsx +++ b/src/course/02- lessons/02-Silver/RenderProps/final/final.tsx @@ -1,7 +1,7 @@ import { ChangeEvent, HTMLAttributes, useState } from 'react'; -import { Input } from '../../../shared/components/Input/Input.component'; -import { Label } from '../../../shared/components/Label/Label.component'; -import { ErrorMessage } from '../../../shared/components/ErrorMessage/ErrorMessage.component'; +import { Input } from '@shared/components/Input/Input.component'; +import { Label } from '@shared/components/Label/Label.component'; +import { ErrorMessage } from '@shared/components/ErrorMessage/ErrorMessage.component'; interface ITextFieldProps { hasError: boolean; diff --git a/src/course/02- lessons/03-RenderProps/lesson.mdx b/src/course/02- lessons/02-Silver/RenderProps/lesson.mdx similarity index 96% rename from src/course/02- lessons/03-RenderProps/lesson.mdx rename to src/course/02- lessons/02-Silver/RenderProps/lesson.mdx index fb3b3d9..7e6dff2 100644 --- a/src/course/02- lessons/03-RenderProps/lesson.mdx +++ b/src/course/02- lessons/02-Silver/RenderProps/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Render Props Pattern diff --git a/src/course/02- lessons/03-RenderProps/exercise.stories.tsx b/src/course/02- lessons/02-Silver/StateReducer/exercise/exercise.stories.tsx similarity index 87% rename from src/course/02- lessons/03-RenderProps/exercise.stories.tsx rename to src/course/02- lessons/02-Silver/StateReducer/exercise/exercise.stories.tsx index b039a1f..ff19034 100644 --- a/src/course/02- lessons/03-RenderProps/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/StateReducer/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/03 - Render Props Pattern/02-Exercise', + title: 'Lessons/πŸ₯ˆ Sliver/State Reducer Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/09-StateReducer/exercise.tsx b/src/course/02- lessons/02-Silver/StateReducer/exercise/exercise.tsx similarity index 100% rename from src/course/02- lessons/09-StateReducer/exercise.tsx rename to src/course/02- lessons/02-Silver/StateReducer/exercise/exercise.tsx diff --git a/src/course/02-solutions/05-Hooks/final.stories.tsx b/src/course/02- lessons/02-Silver/StateReducer/final/final.stories.tsx similarity index 87% rename from src/course/02-solutions/05-Hooks/final.stories.tsx rename to src/course/02- lessons/02-Silver/StateReducer/final/final.stories.tsx index 6b78fa8..d6b730c 100644 --- a/src/course/02-solutions/05-Hooks/final.stories.tsx +++ b/src/course/02- lessons/02-Silver/StateReducer/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/05 - Hooks Pattern/03-Final', + title: 'Lessons/πŸ₯ˆ Sliver/State Reducer Pattern/03-Final', component: Final }; diff --git a/src/course/02-solutions/09-StateReducer/final.tsx b/src/course/02- lessons/02-Silver/StateReducer/final/final.tsx similarity index 97% rename from src/course/02-solutions/09-StateReducer/final.tsx rename to src/course/02- lessons/02-Silver/StateReducer/final/final.tsx index 7414940..e34d56a 100644 --- a/src/course/02-solutions/09-StateReducer/final.tsx +++ b/src/course/02- lessons/02-Silver/StateReducer/final/final.tsx @@ -2,7 +2,7 @@ import { Dispatch, useEffect, useReducer } from 'react'; import { IPokemon, PokemonManager -} from '../../../shared/modules/PokemonManager/PokemonManager'; +} from '@shared/modules/PokemonManager/PokemonManager'; interface IPokemonReducerState { pokemons?: IPokemon[]; diff --git a/src/course/02- lessons/09-StateReducer/lesson.mdx b/src/course/02- lessons/02-Silver/StateReducer/lesson.mdx similarity index 97% rename from src/course/02- lessons/09-StateReducer/lesson.mdx rename to src/course/02- lessons/02-Silver/StateReducer/lesson.mdx index 7cd41e0..185de16 100644 --- a/src/course/02- lessons/09-StateReducer/lesson.mdx +++ b/src/course/02- lessons/02-Silver/StateReducer/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # State Reducer Pattern diff --git a/src/course/02- lessons/07-HigherOrderComponents/exercise.stories.tsx b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/exercise.stories.tsx similarity index 87% rename from src/course/02- lessons/07-HigherOrderComponents/exercise.stories.tsx rename to src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/exercise.stories.tsx index 09540c2..adedfa2 100644 --- a/src/course/02- lessons/07-HigherOrderComponents/exercise.stories.tsx +++ b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/exercise.stories.tsx @@ -3,7 +3,8 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/07 - Higher Order Components Pattern/02-Exercise', + title: + 'Lessons/πŸ₯‡ Gold/Higher Order Components Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/07-HigherOrderComponents/exercise.tsx b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/exercise.tsx similarity index 100% rename from src/course/02- lessons/07-HigherOrderComponents/exercise.tsx rename to src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/exercise.tsx diff --git a/src/course/02- lessons/07-HigherOrderComponents/withPokemon.tsx b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/withPokemon.tsx similarity index 100% rename from src/course/02- lessons/07-HigherOrderComponents/withPokemon.tsx rename to src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/withPokemon.tsx diff --git a/src/course/02-solutions/07-HigherOrderComponents/final.stories.tsx b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/final.stories.tsx similarity index 86% rename from src/course/02-solutions/07-HigherOrderComponents/final.stories.tsx rename to src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/final.stories.tsx index 82482b7..43ddf05 100644 --- a/src/course/02-solutions/07-HigherOrderComponents/final.stories.tsx +++ b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/07 - Higher Order Components Pattern/03-Final', + title: 'Lessons/πŸ₯‡ Gold/Higher Order Components Pattern/03-Final', component: Final }; diff --git a/src/course/02-solutions/07-HigherOrderComponents/final.tsx b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/final.tsx similarity index 95% rename from src/course/02-solutions/07-HigherOrderComponents/final.tsx rename to src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/final.tsx index fe8200a..c3f4f0b 100644 --- a/src/course/02-solutions/07-HigherOrderComponents/final.tsx +++ b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/final.tsx @@ -3,7 +3,7 @@ import { IPokemonManagerActions, withPokemons } from './withPokemon'; import { IPokemon, IPokemonManagerState -} from '../../../shared/modules/PokemonManager/PokemonManager'; +} from '@shared/modules/PokemonManager/PokemonManager'; interface IMapStateToPropsComponentOneResponse { pokemons: IPokemon[]; diff --git a/src/course/02-solutions/07-HigherOrderComponents/withPokemon.tsx b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/withPokemon.tsx similarity index 94% rename from src/course/02-solutions/07-HigherOrderComponents/withPokemon.tsx rename to src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/withPokemon.tsx index 375bba6..6d60112 100644 --- a/src/course/02-solutions/07-HigherOrderComponents/withPokemon.tsx +++ b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/withPokemon.tsx @@ -2,7 +2,7 @@ import { useMemo, useState } from 'react'; import { IPokemonManagerState, PokemonManager -} from '../../../shared/modules/PokemonManager/PokemonManager'; +} from '@shared/modules/PokemonManager/PokemonManager'; export interface IPokemonManagerActions { fetchPokemons: (total: number) => Promise; diff --git a/src/course/02- lessons/07-HigherOrderComponents/lesson.mdx b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/lesson.mdx similarity index 96% rename from src/course/02- lessons/07-HigherOrderComponents/lesson.mdx rename to src/course/02- lessons/03-Gold/01-HigherOrderComponents/lesson.mdx index aa8e0ba..eeddd2b 100644 --- a/src/course/02- lessons/07-HigherOrderComponents/lesson.mdx +++ b/src/course/02- lessons/03-Gold/01-HigherOrderComponents/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Higher Order Components Pattern diff --git a/src/course/02-solutions/04-PresentationalAndContainer/mocks.ts b/src/course/02-solutions/04-PresentationalAndContainer/mocks.ts deleted file mode 100644 index 944b403..0000000 --- a/src/course/02-solutions/04-PresentationalAndContainer/mocks.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { useState } from 'react'; - -interface IAddress { - id: number; - displayAddress: string; -} - -export interface ICheckoutData { - deliveryAddress: IAddress; - billingAddress?: IAddress; -} - -type ApiHook = [ - () => Promise, - { - data: T; - isSuccess: boolean; - isError: boolean; - isLoading: boolean; - onBillingAddressUpdate?: () => void; - } -]; - -export const useCheckout = (): ApiHook => { - const [data, setData] = useState(); - const [isError] = useState(false); - const [isLoading, setIsLoading] = useState(false); - const [isSuccess, setIsSuccess] = useState(false); - - const getCheckoutInfo = async () => { - setIsLoading(true); - setData({ - deliveryAddress: { - id: 1, - displayAddress: '12 John Doe St, W12 5TH' - }, - billingAddress: undefined - }); - - setTimeout(() => { - setIsLoading(false); - setIsSuccess(true); - }, 1000); - }; - - const onBillingAddressUpdate = () => { - setData({ - deliveryAddress: data?.deliveryAddress as IAddress, - billingAddress: { - id: 2, - displayAddress: '12 John Doe Billing St, W12 5TH' - } - }); - }; - - return [ - getCheckoutInfo, - { data, isError, isLoading, isSuccess, onBillingAddressUpdate } - ]; -}; - -export const useBrandOnePayment = (): ApiHook => { - const [isError] = useState(false); - const [isLoading, setIsLoading] = useState(false); - const [isSuccess, setIsSuccess] = useState(false); - - const makePayment = async () => { - setIsLoading(true); - - makePayment(); - - setTimeout(() => { - setIsLoading(false); - setIsSuccess(true); - }, 1000); - }; - - return [ - makePayment, - { data: undefined, isSuccess, isError, isLoading } - ]; -}; - -export const useBrandTwoPayment = (): ApiHook => { - const [isError] = useState(false); - const [isLoading, setIsLoading] = useState(false); - const [isSuccess, setIsSuccess] = useState(false); - - const makePayment = async () => { - setIsLoading(true); - - makePayment(); - - setTimeout(() => { - setIsLoading(false); - setIsSuccess(true); - }, 1000); - }; - - return [ - makePayment, - { data: undefined, isSuccess, isError, isLoading } - ]; -}; diff --git a/src/course/02-solutions/05-Hooks/components.tsx b/src/course/02-solutions/05-Hooks/components.tsx deleted file mode 100644 index 2adee81..0000000 --- a/src/course/02-solutions/05-Hooks/components.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { Input } from '../../../shared/components/Input/Input.component'; -import { Label } from '../../../shared/components/Label/Label.component'; -import { ErrorMessage } from '../../../shared/components/ErrorMessage/ErrorMessage.component'; -import { HTMLAttributes } from 'react'; - -export interface ITextFieldProps { - hasError: boolean; - errorMessage?: string; - id: string; - name: string; - label: string; - input: HTMLAttributes & { required?: boolean }; -} - -export const TextFieldComponent = ({ - hasError, - errorMessage, - input, - id, - name, - label -}: ITextFieldProps) => ( -
- - - {errorMessage && hasError && ( - - )} -
-); diff --git a/src/course/02-solutions/10-Compound/final.stories.tsx b/src/course/02-solutions/10-Compound/final.stories.tsx deleted file mode 100644 index e4f27ff..0000000 --- a/src/course/02-solutions/10-Compound/final.stories.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import { Final } from './final'; - -const meta: Meta = { - title: 'Lessons/10 - Compound Components Pattern/03-Final', - component: Final -}; - -export default meta; -type Story = StoryObj; - -/* - * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas - * to learn more about using the canvasElement to query the DOM - */ -export const Default: Story = { - play: async () => {}, - args: {} -}; diff --git a/src/course/02-solutions/11-Slots/icons/index.tsx b/src/course/02-solutions/11-Slots/icons/index.tsx deleted file mode 100644 index 75775a1..0000000 --- a/src/course/02-solutions/11-Slots/icons/index.tsx +++ /dev/null @@ -1,31 +0,0 @@ -export const IconTwo = ( - - - -); - -export const IconOne = ( - - - -); diff --git a/tsconfig.app.json b/tsconfig.app.json index 3be60d9..23ed661 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -21,7 +21,10 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true + "noFallthroughCasesInSwitch": true, + "paths": { + "@shared/*": ["./src/shared/*"] + } }, "include": ["src"], "ignore": ["src/**/*.mdx"] diff --git a/tsconfig.node.json b/tsconfig.node.json index 3afdd6e..f89e416 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -7,7 +7,10 @@ "moduleResolution": "bundler", "allowSyntheticDefaultImports": true, "strict": true, - "noEmit": true + "noEmit": true, + "paths": { + "@shared/*": ["./src/shared/*"] + } }, "include": ["vite.config.ts"] } diff --git a/vite.config.ts b/vite.config.ts index 9cc50ea..6549182 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,7 @@ -import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react"; +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()], + plugins: [react()] }); From 2130cb17554b80ba5597ce6c93c549cb661fb476 Mon Sep 17 00:00:00 2001 From: Matthew Claffey Date: Wed, 21 May 2025 15:27:05 +0100 Subject: [PATCH 3/5] feat: implement the plymorphic lesson (#37) --- .storybook/main.ts | 13 +- .storybook/styles/docs.styles.css | 4 + package-lock.json | 1311 +++++++++++++++-- package.json | 1 + src/course/01-introduction/01-Welcome.mdx | 13 +- .../Compound/exercise/exercise.stories.tsx | 2 +- .../Compound/final/final.stories.tsx | 2 +- .../02- lessons/02-Silver/Compound/lesson.mdx | 2 +- .../Controlled/exercise/exercise.stories.tsx | 2 +- .../Controlled/final/final.stories.tsx | 2 +- .../02-Silver/Controlled/lesson.mdx | 2 +- .../exercise/exercise.stories.tsx | 20 + .../exercise/exercise.tsx | 102 ++ .../final/final.stories.tsx | 20 + .../PolymorphicComponents/final/final.tsx | 85 ++ .../PolymorphicComponents/lesson.mdx | 103 ++ .../Portals/exercise/exercise.stories.tsx | 2 +- .../02-Silver/Portals/final/final.stories.tsx | 2 +- .../02- lessons/02-Silver/Portals/lesson.mdx | 2 +- .../Provider/exercise/exercise.stories.tsx | 2 +- .../Provider/final/final.stories.tsx | 2 +- .../02- lessons/02-Silver/Provider/lesson.mdx | 2 +- .../RenderProps/exercise/exercise.stories.tsx | 2 +- .../RenderProps/final/final.stories.tsx | 2 +- .../02-Silver/RenderProps/lesson.mdx | 2 +- .../exercise/exercise.stories.tsx | 2 +- .../StateReducer/final/final.stories.tsx | 2 +- .../02-Silver/StateReducer/lesson.mdx | 2 +- .../exercise/exercise.stories.tsx | 0 .../exercise/exercise.tsx | 0 .../exercise/withPokemon.tsx | 0 .../final/final.stories.tsx | 0 .../final/final.tsx | 0 .../final/withPokemon.tsx | 0 .../lesson.mdx | 0 35 files changed, 1590 insertions(+), 118 deletions(-) create mode 100644 src/course/02- lessons/02-Silver/PolymorphicComponents/exercise/exercise.stories.tsx create mode 100644 src/course/02- lessons/02-Silver/PolymorphicComponents/exercise/exercise.tsx create mode 100644 src/course/02- lessons/02-Silver/PolymorphicComponents/final/final.stories.tsx create mode 100644 src/course/02- lessons/02-Silver/PolymorphicComponents/final/final.tsx create mode 100644 src/course/02- lessons/02-Silver/PolymorphicComponents/lesson.mdx rename src/course/02- lessons/03-Gold/{01-HigherOrderComponents => HigherOrderComponents}/exercise/exercise.stories.tsx (100%) rename src/course/02- lessons/03-Gold/{01-HigherOrderComponents => HigherOrderComponents}/exercise/exercise.tsx (100%) rename src/course/02- lessons/03-Gold/{01-HigherOrderComponents => HigherOrderComponents}/exercise/withPokemon.tsx (100%) rename src/course/02- lessons/03-Gold/{01-HigherOrderComponents => HigherOrderComponents}/final/final.stories.tsx (100%) rename src/course/02- lessons/03-Gold/{01-HigherOrderComponents => HigherOrderComponents}/final/final.tsx (100%) rename src/course/02- lessons/03-Gold/{01-HigherOrderComponents => HigherOrderComponents}/final/withPokemon.tsx (100%) rename src/course/02- lessons/03-Gold/{01-HigherOrderComponents => HigherOrderComponents}/lesson.mdx (100%) diff --git a/.storybook/main.ts b/.storybook/main.ts index 3ade951..029ba2e 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,5 +1,6 @@ import type { StorybookConfig } from '@storybook/react-vite'; import { mergeConfig } from 'vite'; +import remarkGfm from 'remark-gfm'; import path from 'path'; const config: StorybookConfig = { @@ -11,7 +12,17 @@ const config: StorybookConfig = { '@storybook/addon-onboarding', '@storybook/addon-links', '@storybook/addon-interactions', - '@storybook/addon-essentials' + '@storybook/addon-essentials', + { + name: '@storybook/addon-docs', + options: { + mdxPluginOptions: { + mdxCompileOptions: { + remarkPlugins: [remarkGfm] + } + } + } + } ], framework: { name: '@storybook/react-vite', diff --git a/.storybook/styles/docs.styles.css b/.storybook/styles/docs.styles.css index ec41664..d5b4c92 100644 --- a/.storybook/styles/docs.styles.css +++ b/.storybook/styles/docs.styles.css @@ -27,3 +27,7 @@ .sbdocs-content h3 { font-size: 1.75rem; } + +.sbdocs-content ol { + list-style: decimal; +} diff --git a/package-lock.json b/package-lock.json index 7337777..39050e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,6 +42,7 @@ "eslint-plugin-storybook": "^0.8.0", "playwright": "^1.44.1", "postcss": "^8.4.38", + "remark-gfm": "^4.0.1", "storybook": "^8.4.7", "tailwindcss": "^3.4.5", "typescript": "^5.2.2", @@ -3764,6 +3765,16 @@ "@types/node": "*" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -3839,6 +3850,16 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/mdx": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", @@ -3851,6 +3872,13 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "18.19.38", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.38.tgz", @@ -3941,6 +3969,13 @@ "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==" }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/uuid": { "version": "9.0.8", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", @@ -4758,6 +4793,17 @@ "@babel/core": "^7.0.0" } }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -5015,6 +5061,17 @@ } ] }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chai": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", @@ -5523,6 +5580,31 @@ "node": ">=0.10.0" } }, + "node_modules/decode-named-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz", + "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decode-named-character-reference/node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dedent": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", @@ -5646,6 +5728,20 @@ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -6447,6 +6543,13 @@ "integrity": "sha512-+kn8561vHAY+dt+0gMqqj1oY+g5xWrsuGMk4QGxotT2WS545nVqqjs37z6hrYfIuucwqthzwJfCJUEYqixyljg==", "dev": true }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -7780,6 +7883,19 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -10347,6 +10463,17 @@ "dev": true, "license": "MIT" }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -10446,6 +10573,17 @@ "integrity": "sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==", "dev": true }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -10456,148 +10594,952 @@ "node": ">= 0.4" } }, - "node_modules/memoizerific": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", - "integrity": "sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==", + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", "dev": true, + "license": "MIT", "dependencies": { - "map-or-similar": "^1.5.0" + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" }, - "engines": { - "node": ">=8.6" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", "dev": true, - "engines": { - "node": ">= 0.6" + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", "dev": true, + "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" }, - "engines": { - "node": ">= 0.6" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mimic-fn": { + "node_modules/mdast-util-gfm-footnote": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", "dev": true, - "engines": { - "node": ">=6" + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", "dev": true, - "engines": { - "node": ">=4" + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", "dev": true, - "engines": { - "node": ">=8" + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" }, - "engines": { - "node": ">=10" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", "dev": true, + "license": "MIT", "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "node_modules/memoizerific": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", + "integrity": "sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==", + "dev": true, + "dependencies": { + "map-or-similar": "^1.5.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -11920,6 +12862,58 @@ "node": ">=4" } }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -12884,6 +13878,17 @@ "tree-kill": "cli.js" } }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -13013,6 +14018,85 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -13174,6 +14258,36 @@ "node": ">=10.12.0" } }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { "version": "5.4.19", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", @@ -13617,6 +14731,17 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index 40ed1d8..6b7b550 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "eslint-plugin-storybook": "^0.8.0", "playwright": "^1.44.1", "postcss": "^8.4.38", + "remark-gfm": "^4.0.1", "storybook": "^8.4.7", "tailwindcss": "^3.4.5", "typescript": "^5.2.2", diff --git a/src/course/01-introduction/01-Welcome.mdx b/src/course/01-introduction/01-Welcome.mdx index 87e2a82..56b3a3d 100644 --- a/src/course/01-introduction/01-Welcome.mdx +++ b/src/course/01-introduction/01-Welcome.mdx @@ -48,12 +48,13 @@ Each lesson is broken down in an exercise file and a final file. The exercise fi #### πŸ₯ˆ Silver -- [Compound components pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-compound-components-pattern-01-lesson--docs) -- [Controlled component pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-controlled-components-pattern-01-lesson--docs) -- [Render props pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-render-props-pattern-01-lesson--docs) -- [The Provider pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-provider-pattern-01-lesson--docs) -- [The State Reducer pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-state-reducer-pattern-01-lesson--docs) -- [Portals pattern](?path=/docs/lessons-πŸ₯ˆ-sliver-portals-01-lesson--docs) +- [Compound components pattern](?path=/docs/lessons-πŸ₯ˆ-Silver-compound-components-pattern-01-lesson--docs) +- [Controlled component pattern](?path=/docs/lessons-πŸ₯ˆ-Silver-controlled-components-pattern-01-lesson--docs) +- [Render props pattern](?path=/docs/lessons-πŸ₯ˆ-Silver-render-props-pattern-01-lesson--docs) +- [The Provider pattern](?path=/docs/lessons-πŸ₯ˆ-Silver-provider-pattern-01-lesson--docs) +- [The State Reducer pattern](?path=/docs/lessons-πŸ₯ˆ-Silver-state-reducer-pattern-01-lesson--docs) +- [Portals pattern](?path=/docs/lessons-πŸ₯ˆ-Silver-portals-01-lesson--docs) +- [Polymorphic components pattern](?path=/docs/lessons-πŸ₯ˆ-silver-polymorphic-components-01-lesson--docs) #### πŸ₯‡ Gold diff --git a/src/course/02- lessons/02-Silver/Compound/exercise/exercise.stories.tsx b/src/course/02- lessons/02-Silver/Compound/exercise/exercise.stories.tsx index b35e34d..2553528 100644 --- a/src/course/02- lessons/02-Silver/Compound/exercise/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/Compound/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/πŸ₯ˆ Sliver/Compound Components Pattern/02-Exercise', + title: 'Lessons/πŸ₯ˆ Silver/Compound Components Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/02-Silver/Compound/final/final.stories.tsx b/src/course/02- lessons/02-Silver/Compound/final/final.stories.tsx index d09a9cb..e7a6771 100644 --- a/src/course/02- lessons/02-Silver/Compound/final/final.stories.tsx +++ b/src/course/02- lessons/02-Silver/Compound/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/πŸ₯ˆ Sliver/Compound Components Pattern/03-Final', + title: 'Lessons/πŸ₯ˆ Silver/Compound Components Pattern/03-Final', component: Final }; diff --git a/src/course/02- lessons/02-Silver/Compound/lesson.mdx b/src/course/02- lessons/02-Silver/Compound/lesson.mdx index 9751a69..739f3a3 100644 --- a/src/course/02- lessons/02-Silver/Compound/lesson.mdx +++ b/src/course/02- lessons/02-Silver/Compound/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Compound Components Pattern diff --git a/src/course/02- lessons/02-Silver/Controlled/exercise/exercise.stories.tsx b/src/course/02- lessons/02-Silver/Controlled/exercise/exercise.stories.tsx index 1bda094..99a98cd 100644 --- a/src/course/02- lessons/02-Silver/Controlled/exercise/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/Controlled/exercise/exercise.stories.tsx @@ -4,7 +4,7 @@ import { Exercise } from './exercise'; const meta: Meta = { title: - 'Lessons/πŸ₯ˆ Sliver/Controlled Components Pattern/02-Exercise', + 'Lessons/πŸ₯ˆ Silver/Controlled Components Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/02-Silver/Controlled/final/final.stories.tsx b/src/course/02- lessons/02-Silver/Controlled/final/final.stories.tsx index 61763d8..56ee988 100644 --- a/src/course/02- lessons/02-Silver/Controlled/final/final.stories.tsx +++ b/src/course/02- lessons/02-Silver/Controlled/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/πŸ₯ˆ Sliver/Controlled Components Pattern/03-Final', + title: 'Lessons/πŸ₯ˆ Silver/Controlled Components Pattern/03-Final', component: Final }; diff --git a/src/course/02- lessons/02-Silver/Controlled/lesson.mdx b/src/course/02- lessons/02-Silver/Controlled/lesson.mdx index f238cf0..77f4b7f 100644 --- a/src/course/02- lessons/02-Silver/Controlled/lesson.mdx +++ b/src/course/02- lessons/02-Silver/Controlled/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Controlled Components Pattern diff --git a/src/course/02- lessons/02-Silver/PolymorphicComponents/exercise/exercise.stories.tsx b/src/course/02- lessons/02-Silver/PolymorphicComponents/exercise/exercise.stories.tsx new file mode 100644 index 0000000..6e64026 --- /dev/null +++ b/src/course/02- lessons/02-Silver/PolymorphicComponents/exercise/exercise.stories.tsx @@ -0,0 +1,20 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Exercise } from './exercise'; + +const meta: Meta = { + title: 'Lessons/πŸ₯ˆ Silver/Polymorphic Components/02-Exercise', + component: Exercise +}; + +export default meta; +type Story = StoryObj; + +/* + * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas + * to learn more about using the canvasElement to query the DOM + */ +export const Default: Story = { + play: async () => {}, + args: {} +}; diff --git a/src/course/02- lessons/02-Silver/PolymorphicComponents/exercise/exercise.tsx b/src/course/02- lessons/02-Silver/PolymorphicComponents/exercise/exercise.tsx new file mode 100644 index 0000000..f54dfd3 --- /dev/null +++ b/src/course/02- lessons/02-Silver/PolymorphicComponents/exercise/exercise.tsx @@ -0,0 +1,102 @@ +import { HTMLAttributes } from 'react'; + +/** + * Exercise: Refactor the Heading component to correctly use the polymorphic pattern. + * + * πŸ€” Observations of this file + * In the current component you can see that the as prop is a string so if a developer in a team uses the wrong element they would just get the h2 element. + * Font sizes are clearly defined to the element so there is no flexibility in sizes which can lead to developers pleasing designers but... breaking accessibility or vice versa where designs do not look the same as what was provided. + * + * We need to tackle this in stages... + * + * Stage one - Refactoring the component to use Polymorphic style so we remove the switch statement. + * Stage two - decouple the font size to the element + * Stage three - allow for developers to have a size medium breakpoint for special designs. + * + */ + +// πŸ§‘πŸ»β€πŸ’» 1.a - Create a type called allowedHTMLElements + +// πŸ§‘πŸ»β€πŸ’» 2.a - Create a type called FontSizes and it's a union of 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' + +interface IHeading extends HTMLAttributes { + // πŸ§‘πŸ»β€πŸ’» 1.b - Update the type of string to be the type you defined as part of 1.a + as?: string; + // πŸ§‘πŸ»β€πŸ’» 2.b - Create a new prop called size?: FontSizes; + // πŸ§‘πŸ»β€πŸ’» 3.a - Create a new prop called sizeMd?: FontSizes; + children?: React.ReactNode | React.ReactNode[]; +} + +const Heading = ({ + // πŸ§‘πŸ»β€πŸ’» 1.c - add : Element = 'h2' what this will do is redefine the prop to be a capital variable which can be used as a React Component. + as = 'h2', + // πŸ§‘πŸ»β€πŸ’» 2.c - Create a new prop called size + // πŸ§‘πŸ»β€πŸ’» 3.b - Create a new prop called sizeMd + children, + ...rest +}: IHeading) => { + // πŸ§‘πŸ»β€πŸ’» 1.d - Create a variable called elementFontSize which uses useMemo to return a string from an object key mapping. For example: useMemo(() => ({ h1: 'text-3xl' }[Element]), [Element]); + // πŸ§‘πŸ»β€πŸ’» 2.d - In the useMemo add the size as a dependency and then check if size exists. If it does, return `text-${size}` if not, return what was there previously. Move onto 3.a. + + // πŸ§‘πŸ»β€πŸ’» 3.c - create another useMemo for largeFontSizes where we find an array of md:text-(sm-3xl) and we need to "find" which one in that array "includes" sizeMd props value. + + // πŸ§ͺ 3.d Head down to the storybook Exercise Component and add a few more variants in. + + // πŸ§‘πŸ»β€πŸ’» 1.e return the Element with the className={classNames('mb-3 font-semibold', elementFontSize)} don't forget the ...rest + // πŸ’£ 1.f remove the old code below. Move onto step 2.a. + if (as) + switch (as) { + case 'h1': + return ( +

+ {children} +

+ ); + case 'h3': + return ( +

+ {children} +

+ ); + case 'h4': + return ( +

+ {children} +

+ ); + case 'h5': + return ( +
+ {children} +
+ ); + case 'h6': + return ( +
+ {children} +
+ ); + default: + return ( +

+ {children} +

+ ); + } +}; + +export const Exercise = () => ( +
+ Heading One + Heading Two + Heading Three + Heading Four + Heading Five + Heading Six + {/* 3.e πŸ‘¨πŸ»β€πŸ’» Implement a heading as h2 and size sm */} + + {/* 3.e πŸ‘¨πŸ»β€πŸ’» Implement a heading as h2 and size sm and sizeMd is 3xl */} + + {/* 3.e πŸ‘¨πŸ»β€πŸ’» Implement a heading as h2 and sizeMd is 3xl */} +
+); diff --git a/src/course/02- lessons/02-Silver/PolymorphicComponents/final/final.stories.tsx b/src/course/02- lessons/02-Silver/PolymorphicComponents/final/final.stories.tsx new file mode 100644 index 0000000..e677c1f --- /dev/null +++ b/src/course/02- lessons/02-Silver/PolymorphicComponents/final/final.stories.tsx @@ -0,0 +1,20 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Final } from './final'; + +const meta: Meta = { + title: 'Lessons/πŸ₯ˆ Silver/Polymorphic Components/03-Final', + component: Final +}; + +export default meta; +type Story = StoryObj; + +/* + * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas + * to learn more about using the canvasElement to query the DOM + */ +export const Default: Story = { + play: async () => {}, + args: {} +}; diff --git a/src/course/02- lessons/02-Silver/PolymorphicComponents/final/final.tsx b/src/course/02- lessons/02-Silver/PolymorphicComponents/final/final.tsx new file mode 100644 index 0000000..58c6cfa --- /dev/null +++ b/src/course/02- lessons/02-Silver/PolymorphicComponents/final/final.tsx @@ -0,0 +1,85 @@ +import classNames from 'classnames'; +import { HTMLAttributes, useMemo } from 'react'; + +type AllowedHTMLElements = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + +type FontSizes = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl'; + +// πŸ’… could use conditional types here to use the correct element but for the sake of the example we can keep heading element. +interface IHeading extends HTMLAttributes { + as?: AllowedHTMLElements; + size?: FontSizes; + sizeMd?: FontSizes; + children?: React.ReactNode | React.ReactNode[]; +} + +const Heading = ({ + as: Element = 'h2', + size, + sizeMd, + children, + ...rest +}: IHeading) => { + const elementFontSize = useMemo( + () => + size + ? `text-${size}` + : { + h1: 'text-3xl', + h2: 'text-2xl', + h3: 'text-xl', + h4: 'text-lg', + h5: 'text-md', + h6: 'text-sm' + }[Element], + [Element, size] + ); + + const largeFontSize = useMemo( + () => + [ + 'md:text-sm', + 'md:text-md', + 'md:text-lg', + 'md:text-xl', + 'md:text-2xl', + 'md:text-3xl' + ].find((fontSizeClassName) => + sizeMd ? fontSizeClassName.includes(sizeMd) : false + ), + [sizeMd] + ); + + return ( + + {children} + + ); +}; + +export const Final = () => ( +
+ Heading One + Heading Two + Heading Three + Heading Four + Heading Five + Heading Six + + Heading Two (sm size) + + + Heading Two (sm size mobile and md breakpoint 3xl) + + + Heading Two (md breakpoint 3xl) + +
+); diff --git a/src/course/02- lessons/02-Silver/PolymorphicComponents/lesson.mdx b/src/course/02- lessons/02-Silver/PolymorphicComponents/lesson.mdx new file mode 100644 index 0000000..7e43870 --- /dev/null +++ b/src/course/02- lessons/02-Silver/PolymorphicComponents/lesson.mdx @@ -0,0 +1,103 @@ +import { Meta } from '@storybook/blocks'; + + + +# Polymorphic Components Pattern + +React excels at building reusable components, but repetition can creep in when components only differ slightlyβ€”like headings or buttons with varied HTML tags. + +Consider this: + +```jsx +export const Paragraph = ({ children }) => ( +

{children}

+); +export const HeadingOne = ({ children }) => ( +

{children}

+); +export const HeadingTwo = ({ children }) => ( +

{children}

+); +export const HeadingThree = ({ children }) => ( +

{children}

+); +``` + +Each of these components is nearly identical. This isn't scalable and can be difficult to maintain. The **polymorphic component pattern** solves this by allowing you to render different HTML elements using a single component, often via an **as** prop. + +## Who else does this? + +Most modern UI libraries (like Chakra UI or Radix UI) support polymorphic components. The **as** prop lets developers choose the HTML tag to render, giving flexibility while keeping styling and logic consistent. + +Example: + +```JSX + + My heading is a h3 tag but styled like a h4. + +``` + +This would render as: + +```jsx +

My heading is a h3 tag but styled like a h4.

+``` + +## Implementation + +Here’s a simple implementation of a polymorphic **Heading** component: + +```jsx +export const Heading = ({ + as: Component = 'h2', + size = 'h2', + children +}) => { + return {children}; +}; +``` + +> πŸ’‘ **Tip:** When rendering dynamic elements in React, make sure your **as** value (e.g., **Component**) is capitalized or passed as a variable. React treats lowercase JSX tags as native HTML. + +## Why use this pattern? + +This pattern is extremely useful in design systems, especially when building: + +- Typography components +- Buttons +- Form elements +- Reusable layout primitives + +It ensures your components stay flexible while keeping semantic HTML and accessible markup intact. + +Here's a quick visual guide: + +| Usage | Renders As | Styled As | +| ----------------------------- | ---------- | --------- | +| **Heading** | **h2** | **h2** | +| **Heading as="h3"** | **h3** | **h2** | +| **Heading as="h3" size="h4"** | **h3** | **h4** | + +## Exercise + +### Scenario + +The software engineering group are using a Heading component and it works fairly well from an implementation point of view but there is often friction between the design teams and developers around design consistency vs accessibility. + +The previous developer built a heading component using the right intentions however, the flexibility of the component is a little rigid. + +### What we are going to do? + +In today’s exercise, we’re going to refactor this component to use the Polymorphic pattern. + +It should: + +1. Render a semantic HTML tag based on the **as** prop BUT we have typescript in place to only allow for the heading tags and p tags. +2. Apply a CSS class based on a **size** prop (defaulting to the tag if **size** is not provided). +3. Fall back to defaults (p, p) if neither is provided. + +## Feedback + +Feedback is a gift and it helps me make these courses better for you. If you have 5 minutes, I’d love for you to fill out the feedback form: + +[Feedback](https://github.com/code-mattclaffey/react-design-patterns/issues/new) diff --git a/src/course/02- lessons/02-Silver/Portals/exercise/exercise.stories.tsx b/src/course/02- lessons/02-Silver/Portals/exercise/exercise.stories.tsx index f032f5d..0bae7c2 100644 --- a/src/course/02- lessons/02-Silver/Portals/exercise/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/Portals/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/πŸ₯ˆ Sliver/Portals/02-Exercise', + title: 'Lessons/πŸ₯ˆ Silver/Portals/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/02-Silver/Portals/final/final.stories.tsx b/src/course/02- lessons/02-Silver/Portals/final/final.stories.tsx index 7bf7e01..2902679 100644 --- a/src/course/02- lessons/02-Silver/Portals/final/final.stories.tsx +++ b/src/course/02- lessons/02-Silver/Portals/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/πŸ₯ˆ Sliver/Portals/03-Final', + title: 'Lessons/πŸ₯ˆ Silver/Portals/03-Final', component: Final }; diff --git a/src/course/02- lessons/02-Silver/Portals/lesson.mdx b/src/course/02- lessons/02-Silver/Portals/lesson.mdx index 517a6d2..75767b6 100644 --- a/src/course/02- lessons/02-Silver/Portals/lesson.mdx +++ b/src/course/02- lessons/02-Silver/Portals/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Portals Pattern diff --git a/src/course/02- lessons/02-Silver/Provider/exercise/exercise.stories.tsx b/src/course/02- lessons/02-Silver/Provider/exercise/exercise.stories.tsx index 2775324..634dca0 100644 --- a/src/course/02- lessons/02-Silver/Provider/exercise/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/Provider/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/πŸ₯ˆ Sliver/Provider Pattern/02-Exercise', + title: 'Lessons/πŸ₯ˆ Silver/Provider Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/02-Silver/Provider/final/final.stories.tsx b/src/course/02- lessons/02-Silver/Provider/final/final.stories.tsx index dfc29b9..78349af 100644 --- a/src/course/02- lessons/02-Silver/Provider/final/final.stories.tsx +++ b/src/course/02- lessons/02-Silver/Provider/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/πŸ₯ˆ Sliver/Provider Pattern/03-Final', + title: 'Lessons/πŸ₯ˆ Silver/Provider Pattern/03-Final', component: Final }; diff --git a/src/course/02- lessons/02-Silver/Provider/lesson.mdx b/src/course/02- lessons/02-Silver/Provider/lesson.mdx index 032ca68..31cd02d 100644 --- a/src/course/02- lessons/02-Silver/Provider/lesson.mdx +++ b/src/course/02- lessons/02-Silver/Provider/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Provider Pattern diff --git a/src/course/02- lessons/02-Silver/RenderProps/exercise/exercise.stories.tsx b/src/course/02- lessons/02-Silver/RenderProps/exercise/exercise.stories.tsx index 4ae95da..133be89 100644 --- a/src/course/02- lessons/02-Silver/RenderProps/exercise/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/RenderProps/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/πŸ₯ˆ Sliver/Render Props Pattern/02-Exercise', + title: 'Lessons/πŸ₯ˆ Silver/Render Props Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/02-Silver/RenderProps/final/final.stories.tsx b/src/course/02- lessons/02-Silver/RenderProps/final/final.stories.tsx index d19b771..cd576d2 100644 --- a/src/course/02- lessons/02-Silver/RenderProps/final/final.stories.tsx +++ b/src/course/02- lessons/02-Silver/RenderProps/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/πŸ₯ˆ Sliver/Render Props Pattern/03-Final', + title: 'Lessons/πŸ₯ˆ Silver/Render Props Pattern/03-Final', component: Final }; diff --git a/src/course/02- lessons/02-Silver/RenderProps/lesson.mdx b/src/course/02- lessons/02-Silver/RenderProps/lesson.mdx index 7e6dff2..c9b5497 100644 --- a/src/course/02- lessons/02-Silver/RenderProps/lesson.mdx +++ b/src/course/02- lessons/02-Silver/RenderProps/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # Render Props Pattern diff --git a/src/course/02- lessons/02-Silver/StateReducer/exercise/exercise.stories.tsx b/src/course/02- lessons/02-Silver/StateReducer/exercise/exercise.stories.tsx index ff19034..08eace5 100644 --- a/src/course/02- lessons/02-Silver/StateReducer/exercise/exercise.stories.tsx +++ b/src/course/02- lessons/02-Silver/StateReducer/exercise/exercise.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Exercise } from './exercise'; const meta: Meta = { - title: 'Lessons/πŸ₯ˆ Sliver/State Reducer Pattern/02-Exercise', + title: 'Lessons/πŸ₯ˆ Silver/State Reducer Pattern/02-Exercise', component: Exercise }; diff --git a/src/course/02- lessons/02-Silver/StateReducer/final/final.stories.tsx b/src/course/02- lessons/02-Silver/StateReducer/final/final.stories.tsx index d6b730c..d458cab 100644 --- a/src/course/02- lessons/02-Silver/StateReducer/final/final.stories.tsx +++ b/src/course/02- lessons/02-Silver/StateReducer/final/final.stories.tsx @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Final } from './final'; const meta: Meta = { - title: 'Lessons/πŸ₯ˆ Sliver/State Reducer Pattern/03-Final', + title: 'Lessons/πŸ₯ˆ Silver/State Reducer Pattern/03-Final', component: Final }; diff --git a/src/course/02- lessons/02-Silver/StateReducer/lesson.mdx b/src/course/02- lessons/02-Silver/StateReducer/lesson.mdx index 185de16..ffbf94e 100644 --- a/src/course/02- lessons/02-Silver/StateReducer/lesson.mdx +++ b/src/course/02- lessons/02-Silver/StateReducer/lesson.mdx @@ -1,6 +1,6 @@ import { Meta } from '@storybook/blocks'; - + # State Reducer Pattern diff --git a/src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/exercise.stories.tsx b/src/course/02- lessons/03-Gold/HigherOrderComponents/exercise/exercise.stories.tsx similarity index 100% rename from src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/exercise.stories.tsx rename to src/course/02- lessons/03-Gold/HigherOrderComponents/exercise/exercise.stories.tsx diff --git a/src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/exercise.tsx b/src/course/02- lessons/03-Gold/HigherOrderComponents/exercise/exercise.tsx similarity index 100% rename from src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/exercise.tsx rename to src/course/02- lessons/03-Gold/HigherOrderComponents/exercise/exercise.tsx diff --git a/src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/withPokemon.tsx b/src/course/02- lessons/03-Gold/HigherOrderComponents/exercise/withPokemon.tsx similarity index 100% rename from src/course/02- lessons/03-Gold/01-HigherOrderComponents/exercise/withPokemon.tsx rename to src/course/02- lessons/03-Gold/HigherOrderComponents/exercise/withPokemon.tsx diff --git a/src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/final.stories.tsx b/src/course/02- lessons/03-Gold/HigherOrderComponents/final/final.stories.tsx similarity index 100% rename from src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/final.stories.tsx rename to src/course/02- lessons/03-Gold/HigherOrderComponents/final/final.stories.tsx diff --git a/src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/final.tsx b/src/course/02- lessons/03-Gold/HigherOrderComponents/final/final.tsx similarity index 100% rename from src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/final.tsx rename to src/course/02- lessons/03-Gold/HigherOrderComponents/final/final.tsx diff --git a/src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/withPokemon.tsx b/src/course/02- lessons/03-Gold/HigherOrderComponents/final/withPokemon.tsx similarity index 100% rename from src/course/02- lessons/03-Gold/01-HigherOrderComponents/final/withPokemon.tsx rename to src/course/02- lessons/03-Gold/HigherOrderComponents/final/withPokemon.tsx diff --git a/src/course/02- lessons/03-Gold/01-HigherOrderComponents/lesson.mdx b/src/course/02- lessons/03-Gold/HigherOrderComponents/lesson.mdx similarity index 100% rename from src/course/02- lessons/03-Gold/01-HigherOrderComponents/lesson.mdx rename to src/course/02- lessons/03-Gold/HigherOrderComponents/lesson.mdx From 787201c7b9f35aff57597676c4b20c239ca3ab7e Mon Sep 17 00:00:00 2001 From: Matthew Claffey Date: Fri, 23 May 2025 09:33:28 +0100 Subject: [PATCH 4/5] feat: implement state colocation + state lifting (#38) * feat: implement the state lifting & colocation pattern * chore: update some copy * fix: build --- public/pokemon-battleground.webp | Bin 0 -> 74782 bytes public/pokemon-logo.png | Bin 0 -> 119125 bytes .../exercise/components/Form.tsx | 111 ++++++++++++++ .../exercise/components/PokemonOptions.tsx | 129 ++++++++++++++++ .../exercise/components/Screen.tsx | 84 +++++++++++ .../exercise/exercise.stories.tsx | 24 +++ .../exercise/exercise.tsx | 4 + .../final/components/Form.tsx | 115 ++++++++++++++ .../final/components/PokemonOptions.tsx | 141 ++++++++++++++++++ .../final/components/Screen.tsx | 88 +++++++++++ .../final/final.stories.tsx | 24 +++ .../final/final.tsx | 3 + .../StateColocationVsStateLifting/lesson.mdx | 123 +++++++++++++++ src/shared/hooks/usePokedex.ts | 84 +++++++++++ 14 files changed, 930 insertions(+) create mode 100644 public/pokemon-battleground.webp create mode 100644 public/pokemon-logo.png create mode 100644 src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/components/Form.tsx create mode 100644 src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/components/PokemonOptions.tsx create mode 100644 src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/components/Screen.tsx create mode 100644 src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/exercise.stories.tsx create mode 100644 src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/exercise.tsx create mode 100644 src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Form.tsx create mode 100644 src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/PokemonOptions.tsx create mode 100644 src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Screen.tsx create mode 100644 src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/final.stories.tsx create mode 100644 src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/final.tsx create mode 100644 src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/lesson.mdx create mode 100644 src/shared/hooks/usePokedex.ts diff --git a/public/pokemon-battleground.webp b/public/pokemon-battleground.webp new file mode 100644 index 0000000000000000000000000000000000000000..87ca346c522eeef372fb3583ea7e7304d7661dc5 GIT binary patch literal 74782 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%0Diu5i2o{yhUiN`*7#T!pD?!zSod?* z3sU05N^EZZixan)MloqSHx}RDHZeYoRQd>DQJlgF75mdV#+H9wFjK`&+oA+8{T>bgF@-EjtFT$o|kO4 zz@)R}#0>7Dvie#}sG@7NAdi6+o?lIm=os#_2_!eRRyYs$TMw^j@5oSF193)x6#Vl; z*YZ0|T|`~V96Ww&J6BFnxPCaCRmf-aqQC5D=GW29c>3C(%UXP^J!IgeHyo|=W()PP z^upB5+$AY75Nofv`~UbdF?zjrkhNv3wX0U6URw^UbWM)}a}(T?Y0Y2??z& zK&{f^mytX!aiDbTXbuoP%w~)QG7G9~LjdWExo6qmCdL?U;tLy9q_P@BC%1TVi_rsm zUX>*4B@~+&in^oYzS2i+YXcdnX>tI*b!$e3zh1>mKaq^IJZywU+ns#MB}`ZJYDOW~ z%3=#mZJ1-pTO?%Ksm=ozZhnT(vRaYBv{LB~1+LQ&Cjyfu;d?gG{-r`MJeq@xD+ZOd z**J2hzsFCwmNrGaVI7$I=h?;3SEJo9L)>h<3g?JGN-v|_wF(RfaR#pM+P@RHiRU%xwHGTA#qKdw=>EZ} z0W^AlP~3f^gue5=JOBm9rNL|9ggF0V0gQhZJ>3eL5PL-lJsgalRGtXtKv9J+q_fb4 zt%qCn&{W)iR~r>+*EKM2-}BG0@L1f`$<_4}==dQO2>pEB0=(odZq=QxRKS>N&3}z< z66B{@f9@y0X~|QTZIFPF8qO^cx%B`bYzS)&n)PTEkvR=85l5|C1$Ld)f)Sl(d9}B| z%ja{&gW*qsb*9z9jiVc|XS=EyhvB)IPo=!q#@rb>z0f{GaM6EU8F?o(Zp=3a%A27O6A8#jPV~LFkw2~(tp|sk15amLVme|B-j&ZQ{f(D=0-{OOPF&|=Zs1k zeWWnVq16Nf>Mp%`B_g`@52W&(3}pLT6T!TR>w8Vx8Am7$=@MynmnQ|^On_W-!yPUZ z=_H(P;%@Q(d0a#B=ng~vd&#N`Rd}xD;Kqj>CfGo|usvq&($yVWa?hL3R$?$Pco*uD zHrtFtZ!I8b8Y%F!-h8iAtWJ>!^AqjA0zo^{_m%1p{PwJt7hZ0&Aa1fSySccZnoBSr zE6STZl6YXe2X5W#HdS5Dmdz570OD7VM_f0^T+$kSo(_dWdE-GV+9g-d!dK<_yI- zaOEpt6ZU}%nD^0TM7n^+jwuKrdmnmEgn@tRW4ZA)`M3^~TnqH+5?K_Z|EE7Z=bL=1 zU?~8Pbzqv52gDr}0z-sP_sf3|Qq#rE1Vp8KKcl;XuD^rGmq^K?Lh%}cqSy}%5Mgkn zUz$5T)8_;-g}s*o>@y14jHD(%mCtB*Yz z8P=yOJVJ^Byy>6H(4ju%0ydK55%10OaPl+5Zx0b-Bzy~Fk%o-}$d+x5Syx0@&Gk!- zfajVlCY)A7*_==%RhO#=40bDBH%4j;V#D)H zZ)iN8Qyy1xjv>LDrl+yW$>6j_)0-+(<-Eiq7i80j1rQCh<5bDF!*|u<%=@Ouw@-6) z=8xch)u{yQNCc#E<0JvcS(YvuT)*gN`LMk+4mU@%>N8$SBJJLT4|@n0_h@WwF;Qb{dt3pX!85=RMR{vYN)}Jd1?pP;P@}U^?FEVPBfss@f zc$gG5^Kc_v2IINYcV&zF@uaY4B1LC@qN)A_*DM>&Of*BLX zE@=Ts5(7aDSVb@drOn>HZx);!0z>@nepV@m6o`=J`HSw!N0jc62l%h^8{3MrW(}CL zF__g#E#3xR(ZE&Hf@sDTx8D3td9bI&Iw;YpB+Mt_TmH)}pT%sSD`gHNJ1ab2Yu&#Ex(cYtF`FgTg#z0wf;G; zo3V7bUtf3S&QF2V5+vB1%A|oavU^NcO-XxlOK{Ab1y7Jr{kXp_5SsSvo_Uy_|`$yq^?0&)8!H|Lp(_Ro2&qb!TiSL}3lc;f; zxD{j%IV=DlE+tKbBs6E%jXLK`v-&0&G`7%0Y`ng(&{?KKxiu97gZrTrwfCk~EYBW0 zh{xC!8AX=`UvB*3-|3X04VoV^ zg<~&r3&pxdEf(qSuGNmkMUzf}YU!+oe*gLc@|3$tHUgI?Du zUH*$XHLIzc9?RF6F)|l35UDT*9vEHl+EOk2LG`5jd9#WIMMxzA>>blc{MH`tS(X}z z#Ux%Fz$H%7GzpGZHIun4ar6n?(ATI)^}L!!Gz#5G_IS#c5+B|HkSBheANny=$87k= zZQmpdQkssxQF`(UU6p}~q-9~@6IQwBL0l6)PhnCFMwrI*g^$jzGnG8YzhYrH{sI2E z1+wIk20&Ja=eNOUbNv?)GJW#3vUIo}4Zd68ph3c5@oqtS5*LoMlxbk z$$($?NU!rpVDB5l0GPN0Gk?J8s9Fa*w6oz03dW2MoFO3c_KmXbGa0I$hw2W}v2s^g zjnF5bR?Y>#H{K^=G{3*ap2EjK(5Ql29JP1wxEFesH6gd_s%ZTk*NzoQ(vBEErC$h= zPRQvUzby84LRR4%ZCT;-@(y@*wFSl4E;j-Gwp2WKm(4kAfh%HB+ z+npq#5C$U5*BdrAyrV7LTX*1F%qXO%`FcP@ex_&>8+2Z;{T1aHgnIF#F|CjPf zyE|^)M!DD+O-uLi^E0ey(vraIu02=rLWW}GicH7m$Bd7g)LibG+wUIWj;P2VVNYlLJr)6Pu z7J9;#D5YVDafBC9cXeMK;C9Yw`w!`LN{~$8b;k3Loyx}49cBtd6S$KaWZrY|`8RWM zJ|N52l@pSt^#sW`8E|sr!#3i}3sQ;B z<}8ykpeclG(7$sfKP0;Y1oHeSXy}nBQ0YW*6|B4?h@_Qr?J6C2@pF23Y$EsM6)&o5bgHFRZS5KY%Xmp#f^?93lqn>tTFAF-PbcRtZ)b01dWg}klrnAQS z^m>(5Sbrobv+@0s*U%EQDlB7IdfooZZkrvV&G4yFxVg4qx`C<*fq+KS7Wq%>Y%e@0ZVq<7x@bq5Sa?PE97D>R$BTfgR=Q{zu5_ERudXO$x#82_-)W}m5!J8 z?l+8Xr8D4`t+HgFfq%}@{>bRsNjOdEYcpx*npB82z>=57e6GTYll(^j<-!Ewr4}|B zf<5(n!40-YL2I*|1s8BZx^p7$QV~LdtGxp!f`x2xzvM+5sOOTN*SMrmk6|>-Quf41 z>Nuc|hV19?#*!6ujO^ZKm4HqFNO%~&p7`5y;Nv8dWKp#zHoUR;FR z=%lGV!NM$dq3(X+yn$7>7zt7s8#yg}2@ZRTn&%*QchLnLZjwLr>l)>5BIvn}A&|){ zV;lFw&>z71)Ld}}J(4$H<4@3j5HDccjZk5rQxG7WEf`7%EQtb!^>C!&5r0}lJl`1qjd*wuf2U60dl~(wo~i+|Ro#B^I%mLR!5vBy z)iYDn&lqFuz1%cAVTf|=xCQfi;=w^Qf}Hhal2TZvTlqCFKR|g6ZmVrJ9jvLq(!KPa z_x2)Jrs|AN-wwcWEBBAcbid&D6W*&%@#-|YqB75uh(3vd38Wm7 zMJv(_HLj=A;tNei!+ILarQYc6A%Uu|Fu3gXu_^HKAOH7GsCKV@6?r9|x6VAxU*qNs z)w8zCCjkt*u43~EVZe6%B27@a(fzyEg-NeOr8(GwmC7n`Z48d9x}}7AkB6bz+fc8% zeydzh<&+3u29DKg-OIv>j`nQWpOr1`wR*bF4Pp%qtcGGxe??K3-K{^r2R@EFt4Low z@`t6EHx!``&p?87fpW}f&Gt}4oz->=C$k)8X+JFpmvU`*<3XPpG6?qIIa&7W=4e5l zYanE`YK>_aQp-Ykp_w*En^6SYEm_~_%svbN+qqcn8y?spc3$0&872xM33sA*FGYx5 z0$QAWr}5JM#85UufW~icwmtq5j^{1(Pb3@ku(8lmnSsYyy;NqftNL=h$n^1(n=`*B z*nQvIOdXFuTi#o1UgFS1Ws$PPK?j$dm?TSqz!NG;bV}eI|780LpMdLVIk#NIl}dHj zm%IC_7XXw@H@p$7x0yD%Qi4{PSMA!7ADs<-M33}ZZ&MrH?;Sd+Y-&YnP$tapifI7~ z>1}zHc#moLgcze|*E0?7PfI?#H*M+=1C9SGP4a$O#XRiM##pUL$u`n*6+c{?aFE%8 zJ}S@R@uK^MY}NjPqYEV+dTh?>VE8MzqL}*BrL@Nq-TpF$jtVR^l~YA4pR=eVmyq;SQn@h`^`hX8M9Q9eRCm8j zkz#CWT!OuN#bQF|ez-o|KYx%G*t!zvf06xZz?yS(_(&9KGE5TCA6zI(h_i`%$Id=d zA=Gwv-|X3T8_RjGQbI!=uYrlU18-*G$r)1KY;bHy<}%Aawj<=^9pKvDRA+SJ&(n=x zKuUxdX(Rf43sj|aLHx|d`CQoyh-GOP`9Nk0G3=zQcL&x%ED!3^@2L2*ifvfaXWmTD z?!ladu~FWN8+Qqwo?h#+Iuk_EXs(~qWx~bn^1;iPjJ&i1$8>lWsCy6=NnA3s|+9Im!d; z#QC*;Dr|IO_&=u?FBrR-hO^tnOZwp+^Q7XnX&k1<^+&WK&u_$Xo3c2*b<`91jp&?x_w-KoUb=D5&%EYK%WUP6HPl#I z*X9B(!x32UbrfWUGDQ|mCZYv+zoS@0X(I$M7($Rw2uhH`Ppv6-}a(s zO3z*$V7y*N%EY@_PF$r2%~av%c*1o)^};uf$cNPS!zHrp3%OUE#zZFd4{43VZ5nUf zZMw6OWQ3{7r<|<=5iujn?(4~n3HdJ3owKJl)2J z1O`)D-)xC?{C|0Rkrgv|NZ2jyh)3e20|jq=?#Y58fdC)ySJM*DKIWM-qZt+J`!h}M z?p!xTzW#B0d5+4!Qzd5*Vwa+Qy~QFvZ5_+jSUgW3ov?!$MfiI(!r|dy;Jn{KW=ZSB z+AVkW8~a#OLSI}PETru9)@xa@{}q@7c#+$CO*C1L4>qG4E)zE$>j3RP@#ADX8*grF z4C2Mn9luo9nXPAs0UW#GdG*?GS`$-kuXylMvQhgVBmaeXe9(xF2tPA6Vw{#o)z575 z!mDx-vaK;DWc6LZ8_;S~9CrTwh33WDzTOcsL2>PGD+djaL=p2;I`gEo9K2D#m{@>x z!Qv}#L;XKMHe~Oq&!|7xS%RN#@%$ASIYXMTJ@XiS+sbY;OKUX`T+w{?LQzt~ww?H0 zHLfI^TFk0Ra52dC-tOJl66mwl(-cxpFQa0#pj%}6g$%E4ZzBpfC3HdWnM@;}tQB4xv%<2YH}~ z%1)tbOy$8Y9ngK`)jn(NPLE2Sp>>&6rhOQ(2X>r`&hyGbY97AAxY zR)HoA-l&c$CKe4XPanEKRTY$*H}0=(2=iwb^*yIAw^nB`^1GHLJof2*CK?04 zy4H;-+HW(BP8>FAiL6)h`YIf4Bw!tNa<$IDCMI|4t%T4$17&hIfb0W3X?XlLqOvaa zt99;cFA2FFwgqo;v&`Ptsdg|VLg1VaU@;>{@%E{IT>uv3m$mks?I$ll|qch{BT?n|d)cR=n&BOgDeLk zxRSN5m(fANEaa2I2vvv@67OV5SB7XL%j;zr`M~c_H?w3Vs+)U6=c$V_Qur|tm!1wFs4m}AE0<22dX^3YMp2j9 zg?=QAxD#XnI0TGokCgorahyB%=?sEO@IUiXnLp4$s$WeF>qTRiBeC7z_Dik!xhD6K zLS}iAtlnBL*)-3UKe}QbZuT8u(!Eh<6 z%2mc*te1g9M_gFCUU3RVQ65wv}(b*P700=@sMq36!!hdD}2M_=QRU(Lml)=50k)j(S6U zwRiNcTBs?>9;(BoqR*3X5cO!OX#fk-Gb<{do56Omd8}5 zzp!LBuoL6@eRsT0$$IC&Ww>}h;$yzjR(;}G0v9d(;&OP*mn?~FC%UACp;}E&fSYUb zbWKr)3&S$P_@GeDGP(B?j-eY?=lRs%6?dm2c9>{?eCC&b<*3c|KniKY{#t&5T>T1j zzYgiov8`v&zfH6lz5<;5pPdQ(xQ#1C)!QA~_R*cao5xbaIh?cqk<7h)cV#W~&JLU* zCMR$Veo)Ka58ukj$NDxl?t;1Mp=s{6Uf2|hD>p)PGg3PjW^E9;fLogAe!1`ps$21~ z{9qYTNk&A%TGDf)Mia`v;E;WN9Q6Uv|2!ydEe>Bbk!>B+F}#8YzV;BlXv$!&Pr%O> zQTAtI2Y|fCX;z*4g;m+3dG~i--TJjKkbNWAtk9F6>7rEjeM;q_v1rh?*-M*ZbvCBH zp?+#G2qW`@21lluBrcKU*02yQH)(u(c^0DtQ`^D-vuyY=U5h7mPD84F-0cxY#C@0! z6oM%ST3}j8{_|<|<9kLbA^C>8s(xk&X=~WXYw4Qw2wG=W_4=($fCCSwV(=a4N&;M! zJg2|#9Sp}Ux?iKQ4EZsDzUP!8>*GPGl{z-L0?)-ql`H!3jkWwDVE`i$3}tj&sR~FK z$=q)ws44jq0#$DJ^u)+S6P{Am*5bKcckMJv2GmKJj7(k}&Mv4AT{ePJ1TG3{YyS1w z@s?X)c?>PeG(J)o+5LS*L{Q?_-KE0wTTyf7@ge6Vq7S=c5RFfMl4}acreVtHN%Dpf zP6)(@{dX>Mwg3p!&zwg9(1uCI3>EKwMu;WdaCIRQ2M?36*?B}4lU2G|MOZ>2YF@{H zmV65+!S&3y;08Cco!g&GqYd*rquVfYqUZouhV-33yq5BSeGm`bJvzDj20?3?<1inN zavOwSDmv2_t-JOfrfaRVt2tV?I2M9JSMAjriF3OE36p8-Lnu4~P9lz*iMO+aUw6>v!tL*{#H~Ipi&}mR`a}Cw zq(x#i|DNUx_UIqMGnG4tmag94pZFQ8M|C-E#WA7Et><_U5sFO?s(|BDki_B1+R=1+ zOsr*)!A>&?JcvP?75PIeen2;7*1ajxyW!{uu9O>rtPD zXlbapqu<1546IfvG!n0*%HC@g@@Ebb#wN)G4@CCv?Ik1W>(%gQ{WM%wRQyup&`MGd zfI~K`g^;u?fk7}r98OHtugIaC(;pqH1a&bSs3m}j4VKg%239<0gwV+q$4n)2iQOUuxx z0*$O5qbHK}hvZ&HCo3NjF8hqi2wf#6U1?o#C_5c=oq#H|RBS#GP-l4CPZG>K)^3!| z^Q^~_R%wH-{6i?=Rxwn7+!OsJ^8@}55$UL{&*@xNn#-`olZ{3UU%Hp|;ipnzPmU7a zqq%IGhpToN4-QVt6-P&eD*ew!T}7>v=>gkuYF9&?*mu%c zJdg3lPEYx{r08hK{-;+lGR6V5;47)}T7>HOGoRXyu=%?0ddLWNogwQ-99MG>1V~Mt z1%Kr=G#912DcS2&Kzs(+;<>8X;XkFc89_5?o>^4=ppjxxP1m(GW?*eWHvDVs#xB?6 z#qP|uWY;kXlV7K~PZV|##6|C^FA3dno;Vk^r$9&&`3NpS?=TO4DNTU|CZACgCOS%3 z8MAGqz9MzCWv!KG=A1e6H&+O(s|uXXJiToi6^uNuJehVI-H~dKAMC4|R}Y6CPO~#K zsFdZ5G4PqS&L|+G%tB%?j1Bs#k6Og54NuvI&fLsh=XT<73wgK0^QPXA2#0n109TNj zln#yD`?kHekyj(ktKmYU18oz_wM0l8jAD|+oGeSUye z@)3?FYi;F%pP{Z40ye+q;55XV9QawLfKmZ5#G{LitQ6v!P+_9fr|DI-Z{CI`px`Pn z?1XD&4;MvpoDRs%#Z@)$up%AsB3 zOdAQa!9nLi&VVLYHZMWv7-&iu3C1z!k}(^Ts`aTH2R3Iy_<+hFjumIuUXm-*aMD9~ z8aSQlfpVnx8oap>ugAd3ndAIxN|!2{dYB_Kx*4+q$26}OEkQyP0dcIMW*#u;_lgUh zuc?Jw-H-_(4G@LL^Ig&Ro_B4NEVq0#BG%pyc9-MaOcsRN<6_1wYhi_}5$B%ytfxxo0}E0UzUV9ShJ3=~Ib~l7-kIG+KQ|s!}&*HW<_tkCWQuFF(=> z#-r8RH7;e#)HmOy#KB2YE%63a{-;$EWjv-v-IB-R8R(NW;mwdx2ys?lkK4gN^9t%- zZaAMw!d9qLY8N*%s8AUi>4(YW5+Hz!{$H#kQw93jRm4U0N5dh8-$4C5qe;mJ2~JTd z0Rf5D!|gW2;uI-Z#3j2FHN0{3Al`oNmRxHw!dnW;We{k2BdO6} zO{n=SD@#R<=?k-M3K0Iy2B8+b`1dF1u_kmA#3x2PPPhV|FCQafzBt2#j9sBXs$3-b z61Y`_}RI_M~>_Y$o{WeanfT<~Y{#x@apCNvixN3>NCftp`kkOO*KOmB9pPN`FP^vE!Da4tm90 z5$bEYJZf(}MmRU3I)no`9*<9mxB#&_M&6Nljj)bH zIu;shRs&Q7F0LvZKt5~+(+S2t|ni&2TqK&bZox46en$DwiAy_O+!BUAEHXCJ1( z$lIl2^kfW6U^Ka034NinuFD4cO>!2bnHhNOBq-rCm(wk-O17!fLpsN*wF9bz#03DjT+&}^MOd?T?$=p9ouT_@1pWpSI=y?>F5AIR!Rbw|*ex6y_oi*$BBmLT`N0V5!p^Qt24 z^M9*rQb-K|rK`H|lYz)#6^UXDP}3>qhvvm7_?Zi-SjoR$H_mH_xjb~ZfPu#VWp{~Z zZVBQv^X(C3z|j=+v+lD+w$<6`n~CKW!FcxrBEO04hoc@0pw8AOBx zG4M0)8_PCzTeXgJ>SplYyPuECJj92m8;z|iPEv=wk@F+lNV4V=jekCf!3a&w9rl#1 zu$cl*_bq(~lvG-3ujolET)A}JChEnJcIKH1TAnr{PWIaATeHojaj#lTOH zAMsSncQ@Kq)ZXPYbv#lvT=?H4AbT3fRgUfwOSU0MRNaiUUB@Bmgf-Qc=2gr^+mj z7Y*kBc^8Rx@iSh6V@ggv4;jM6ptP2y0XD|7bAO5fQG^w6Lcxk>aFQ>94RYJdDbUSg zf_?zI!_+c#Em$iAN@X|2o}kbr-M1h@-@Ez(P#;SsYBaix(@sf!)C*zI?7m@wYgog& zTxTJxCwOVWLdnXq?fp^vkdQ0oAmT%OdwUb`x37NM67Q3Zr;M{MoA^Bif^K4B#k&(B z@=kk(gRWG6jWxS#Vf8jZhYDjf_`{ecCp1Y_Cm=cIutQpduD;~e*a;2*(+`*o@^Aql zZ2~Pe`8JY zGHG7^7B5smB;e!}{MJ?jq_L1oga)w92g7x^HzHqS*?Na!ztA&hQy-0U$IPeb4+3 za4tGU-sTNR3}YW|Buq=T{T!=@YV1Tyy8xq5j_ovti%yWmITZwmZ&c@0qo&;mdC|cb z+%Qg$UHA1oA(jdYrH$X7r6IONQ8lBz(n!Zx^d)+2aI0Oj(-;gKKW*wfx5f8JwNqFB zpF(e@wjhA%OTL<$R@o6jGGTkXGTr3NBF4OFDmj z;HU^4dC}ko4WwcPI6jBwh$o2|L@IG8i6Xb(uxiOqEg7B&DorlWI4)uPmZ3Da==ALb z0=f$wDigGe`HH(nB|Sfca=_XnVL8B*NuE-BS;FzW#2oiClK7+BVA)@fk$dEci1pZ3 zwhJo8=|uKwrN(M}U+SfU#^?NI!glyRP3fp~P;*(SGc+*n$(wO;*`H0}EhI&NX}DE)(aNx9_fw@&^%LnMxD*2x_yxM*C^7 zNH0r?k@5VLz%sbOfI>U6fA6)Wi#`Xg^JzHI1(v*7qo|uVoP^i*zquVR86HocsfXJQ z6XZp~{}=Xex(d~nT9+DcFhyHK$cmIf~X)pYMQGi}Xrb5Lh%2$rR=Gi==BLk5H)6h(S zuIw2AtFZ9cuM*UuuTf?Lt;3?xSz%59Gl^Z@s*+f+>h2A-wt2E*1R&RdkEe=81@zfo z&7ziQO48rW0phyAKhj>quPlr4ZtM&X?DMk4$ll!URri5-$YZO~vICjhwo{!aX+^^T zs5n0UIZ&j}sdogMgQ>3C@8vQCZB-;!apaL%uMk~+9iLr;jVHn{TZDTP_*;A=)IVP@ zkWS|^*OYlPhv{e=k_DW+K@HI(xlP_NE#uLD|JwM_P7tX7FXk7H-CeTcCA=Cc#6W$MPc zaJvAugj_@UhPby3KOp^~V6#i=v}o(c@^+%zyNZ4P6%v8HQ722DW2gX1w$AQ#kwB>Y zVzX&-xKyqk?Nx|BaIR<<$s(y4oj&#MHSqQ&T)-#yPlaGBt90B{cK~Dv4cE5YWaIk3 zV!+|?Yt@pQlVkj(Vy;)1v%CS5=nDPQMbig3V`UzQynq%unJX^glmO7bdM@~;>pE-P zz|Y1nT>xw2$RgZmIMRh2Ar#e|M78`x`7n1J}?rHE4 zCCPlzof1*UwKdU0g&FSIGV9$T+wGAjf@MIut6}W>>TjEFU5x z8VZ&HCmb~awwY<>EMrafQ=(X|!IQLF3z7J^VlK;caafK zFi<9h7nSEYDmQBQamzJ@;at@hf{;vTrJ4U-0NH2cyPfX8g1O{xj!)lb#aKS=o z6kqAzpDn}HD8L`e1D5Pvwr_6$2fp_maqd@o0%FZYV-f1STHQjF#qUB*N8-Tr`ChO_ z%5oSgQz4-kz9T)!8#I6z*1Gbvq0_pC_pW=12Ae#tMy?#HslqkhbmHXcYONbdsq8&! zm9RP`!aK6pb`qi;MQHt>$G(2}#$VlIK|gwx1AE#&t~XnLlgcoCMN(TmSgeZfPBxhkf%KIIJf5M>7JB3dW5mx;B!19F)|4mabimF7a{EFG2Q)>jnOJIb5Eui=7w@mK9 z7rC`a$eVdQ6vinvs08t62RoSM8n=DaPpcA z0(amz5@W|z-<;DXm|!vcn{cmX#cJ`JU1KG}1hOv7vICiT*G~>k2g#C-aAn1%qbwafcjYVB&ZS77FcQnar8&C$L=)tK-GPFZSx z_u)wmAq3fA5~j)GL$RzSz`B4_v`ZTJD@~8RZ5`-=?9M?hifyRV>J?&&qxcr$$j+C% z4iD$1Rhe1XmTZR3!cg(e4Oslklh-ZZ*Z8_0`goAln5>_+0h?7E|VwspRHsvlaew4k@tbb*{(c&a=>9yc+QZxx%auRtn+_5cQWos<3i5v-vm zM-tYB=#+jdNc0CRhiU_?FumkP)s+nNIl5>Y|I;OlUAd!R%1|>~#_a@sK=oF|qKzyz z31m~!`B^6z$`mPsulKNVu9U=CA`JW$vfgsY4?N{h27pxkzkpnxQ+vlPJS!xK4pilw zr%yXrw|Mq#DqK!sM6{^ETg*{{)XmqJa;KsSO=#3Ho$O|xq%}f!*UHX3A}BkD^)~oH z-)}_$#y?gavi)LxFtl|dYPu8COL`qX&?I0JyZXVU9=t7qux~(ASO#T_jGWldyJB%m z}V)xZ|#{3wVgCHfi)igSyYY(Hg{@C@V^raHN z-ER4W@1T#W-ANO_fH3me!<`n;p;k(Dli zFxOE|7UbW;7-;97dM#Z^hBX;EFDtjz8a0+ny_@C7`bs^>%*KHu-Fnke=uLo==Q4(M z!}Wjv^@2V#>*coE-koFg_2WYyGv^#it#{>yt^1Yo!T+YrKM3ku8i z?FbncZ`JhNJHZ>+IMLQxA}8;L`en#%1gfXvG!E+qo>r8&KR$#2WQL8h{s}XUm{7{I z8#Wr4XRo)Mx;NL_kF&w^Uj1%cGGrK?ibKStua5OO`1{ku=@I&_GlTPnKa*pu0fM8H zdGJiwFB>ywjUFu+njnp!HBdmKa~=B>r=N?=O8}?V{GQpBJk5cGz$v1uyB#JOUN_VL zlo%-IH}gsE=5tyxoB4g~55_G;W78DFrr#m!9}*FJ8c@PRq^xOEsT)Y$YGNj|6lHY9 zIYF;k49w&K*&fK0l)&fuyZ25wrTFB;$vhy|?57JkwOWEVlIp@G$QQHh+hLAzL^JAHkfq<3r~xsR?XI(Ey(dY5EUjl$9hDdv z*GaG?B2@nSnmB;TRl#}xB0Ro_ZWn7We8+Q9N3}9)PA+{*!epnlMvczzltGYKT!2uY zr89=6=j{-I&27tBccN9*5uy6Q$RGx~LR1MhUbDx0YiN>#Ecj&gdx?&$KFUptIjY zl|m~HV=6%^0UG~_x*T;li?n`dQf&xmK*S{sM{GNGOYJ1!cT=N4Qz}Q}Uw5(CVJuLJ zM~nlLZNe_Gv^b3)GN1*;PLgeB)zIo``)0ziW{w|?ZY-@oN5OJ|E4Rj0u3RaMEW^fp z61B_1w5yXrBlkfoqADz8dGy?!dEz)Bo0I;@1+amkC{bFYQ5bW<88S$qOOha}w|Xw{ zy})oQlyA2rRmzl+x*LUVnq8!%l|?HpA^i#A^fbas7Cx{LP+Q4vV_lnuU{ zaaCwB>t%WA0XudYZZbxsEAC&Ao?c6@3rnRFy&dDKLPMgqL~C@hnYsp4=4xSTvb4tN7&%ewu}KyfoZ z!}Y~i)R()+1++?9sDKN)iED(@q0N$5;6qV-3Z{9ve&*M^u>SHxbpBkt$BbRq{dLAS zNo^(8zlXt}+9*|^AJT&6DB)lJ$|@$fjMAjC52HUHmo-CYR>g^-Q(p^2;0U&u4q-t( z*A=U=In_juLumh?5r#oiU}g_EuudcQr$(d`W&bhG@~-~s`>JvG5CVq=!vHkUr>0dY zAi?(pJQtTg+omh^)`76)C(N}bQjVknuzW|CdrrGE1DaqplIPgibG^byXlgwHk_6p& zLUTSorT7d$GLD|;Dq#PqP6g-|en2I4glNKOPBRhKQUE#P`FD^+u}bPsceQuGVOZ31 zeqF6rwkcYTSMpZu6=Tq?D2p0o35`f@_5JM)7K!oqM-1ob9STZIKIavVdta;naFZd1 z=9D9eRyN1*d#zG!(Hy@=V@faeT&#Vy8&7p|=!cU&AMQws+qD+7@ay)ihe)1I@kuc> z1Ld{d)Y9=*S-0tt$)1V1eyPCMT<|HHf9>g4e{ag$Unlg#9Tm(xTO7v52dLJAvYgCV z_FnyquPw&Sa|e~m2&U;JjX|jeo?}sYH4M^vDl?#Cf04mRulu1Xq_kiwK-#VMH!Pg;{osNXu4{QBjXmIYgedk~XMEKM=a>^L%y4g?f7 znJa+SmAk*Uo`$7RGQyj@D2u1xYB}7QD;G~rOw=Yq5~=&_)oXMQNloxDg#WSicmDZs zqfCzYi*Ac>3ed%^Kf(y_yl+5gm_ctXtb(-@LdKF2u!+1$2*h;&K0v|06Rf{_(lHg3 zB!UXl_Mw`PdP--XY%+4+?2<1MjzdGo3dW8&35c&m3Ny!cEjS7G3L(>+zW5!u2N z(cb&OvBMgyn*1;aj)b^_vwFz}Fuif(;4DUw9igw{nPtZmIQ9`n6g-z-))e^CWsZ!JT4)%l zd`8(M`U-$>$on#$(*Pl(cTCcBP&Zh8tQg0Mo`ipe#j^Pzr#HxS?uuc{r)T|gL zhAF#1**#E?^F>7qPzflu7}Oj;Ix`GdXBsVW$}?^=du+N|xMCL{GxXh$O`C}m-4|9v zr;RjMvP(n4oYk>=#=xN!RUfb-Oi-5DD&yttBHz{ta?-oHX|k`I?X2t<2UB@s{}s|Z zRoKT?%AP64h~3mB%nQy4_EOl>;B964vGXDnVa|O+X{l@t#`$LxFA+!~W2mknWZ!Wo za$llr!e9u>ID9k6Fv)qzOcCGRJEqIDrtpqOtJciY@m(;GXb+Et5L8#W&~!LBMhmv4 zW~ZLaLs#(ISTaVBJH$rQ*>-6~8EZK?g+0?Tr8V5zdszNHI)UAwPOCbX5B8#rB5Pa~ z3Jyo)utYJf4$2R|yQiPva+Q$b-`{FTK}{&-!Pj0UuZ5i7)#z}IQs!&QOU45hPpz4? zAs^-c+gJjEYo?}=j=NS?fU>nYHmpVmwyzSkF0nsFIVtEy`TbxLgFep`Pk*QREEq$sqWV32nf2 zYHH|Xz|i=bHdbO1?bpRp_d3BZv}YL#G2azQFG?5;nD)kiY<7>OoW>A4`t|o@UR`k9 z1GGw2Wmh|5!fuX3VcYrdEaYfC{b4-!f9g`?iPnDp!kxty~gS7Q}(gAT{wb zC9*Zm1!hYtm)GW?ktSB3mT$@D1GU}Ulh!uU`2ZC10)sLv-{lV;x^)-m)gTwbm(Zg+ zlw-Gt{BZooW}uQVONlN2Ri4?@rIlvTA89;oK)}UH`iNf3B>1sVj~Xd_ zCZ1=zivK2_&7QlolDLW~QGd}uyt1?clNc8JmX=H)yAs`c_vHbNY%-sed5%Xb1PVLm z>E{<6h^GNFd96_@dcQ z!}U);JmnE@yozVm?RL84vgJVtKCX79>5Fn7k84xc;t6XGfR{YFeHVf2mFxVdu6icE zysgtK57i#L+{wA9J&-+=F~51uwPGp|ztMLDsD~T@f^y9Jqh&+K*|jZsS2FzPiw@QR zP}kgS=34kxV2tZss(YLy|(+EQloG)M&_G;`WrfVpH~T3tiTLHa6U z(@~u%qsznFDy4X3;W>df8({Rb^WB{#mQM3HuB+-rlgnGn?Hix;OFCG1j5kz%xm}oK zL0{rhB^GV5g>Q8b#dL8CMzj`y@q*g2i9ocqP&8I~7bob%?N4&#x*8h1yVC!**r|;1 zW5vq?)$8I}=@bh!zO9HlAu<6iM0OV7vb+0oEILQ5zAno%fdF)@HSkSwMJopv5UOY> z9&&1PI;)#f)`wNs|GN(Z`BcSsxorg&=R-8 zm_&ie27DvbU3$LN`cgdiV82K3bhAdmkvmu8IDD+37zqv2Uw`nYkbG5(lfQ0r@%!D3hq3Vs|(Eg1C zj<@$}(-mcR>I&{VAQcujd+SGV#YoTgyv*|7`rhN7X=T>BN}0v-q5G3%9MNbIM*euQ z>?*!#Q}q4=Qz2YCAR{$*KHL?MTE#u9#m@)IvVa8v3+XUjd>MgCiR|pIp6Q-wEqJVy zeb5lK0^x@aXz%=KUCxGT9jUYlT(gz>e2ni+{Fb-(Q!k!7x~@vi6m-%@#@MabkyUq& zn3Tfw67)QczE!r7t$M_JDu7qgPY6}Izkiv~Yg{wxN%G8q*liMkfs#MK1{lg!JWac} zMXm9ZfbyWP11QJ3#R2OHBpChwPzDMdztpepGsu(4<1xtBA7bksPwBb(K$-q~v`A}s z$I9mSNU0FCJ?F9cJ$Va+AH))>5r;UvqN?t1XbciTTW%#MFx~+PjTL*R)v$!uD}$yS!F6J?uKchj{b^wMK6|{+|rdogd-IS^yozH z+?8+@2+JfudXYp2N)ZZ5$cHOM%@b{vl{)sqRUUjiix9}9=RXX$!6k7wRHo>jxjgJ6 z>sIy8qlR0kESEE=608>j!a<3l^X*Tazc)jS^%Tj5xAEE5NcNdIoz#t=fV_At?8Z#F z&4Z7gpjZF^iMk$S9MAb*zA)?vd_(4VhL4a&3^8o-6xfIK|3GWkB}EU*qyn8n-4~a| z_YK>H)+Ev;J#5?-<@4L1EMu->cwh2BZkiPx=<>A~KFc<2XLy}{e6|bB$RP4XP`+8z z?5zG(6Vhk-NvBEyvhQ+?GPbFLcpn-ejT9Dgv*YVzCwe|RKhxJS8%pjsZ%CNcyCw;1 zaE8zqu7Zj_zOy$94J_Sq!KZI}7(mjcHI6;OIHZiG1#m9PL(pZA%a5xN%&?cK^@1eQqB*864eULiov-ihSNjCl&ZMxQN_Yjp3Sn_qUXTS-nog+g(JK^+a=;CEx#)@frmu-w` z9)pPgTEtVO>PDfX>$wsZ5eK`?*0~-l`83LZuwjwl`*GoZVFDxahB}05D+_V2#R+&E z0V?AcsnCq|c|;+EKd#`l{1gJ-AQDFkX>=1F2Hh!3oyrIqxxHq^@WP}(UyoD0q_Z!NmK9;Ul=L{##qkRA-K{x6!M2DAmp0sv6h--2g%0G zPUofiO`!St{2TT_t5#%in7F(bZ&GZtt8gt!)3kP$(W|u$IXh`=9NA{22CEWxQf&%wr~lSe+T%P zx=O|H#3FqHWHf33He#F&pmLTWs|#9T5MeeoJP+dabt*!QiY4VUf{_QM$nYcJ}gXGQJO%w|uD&J458?CN?#=< ze8z*n*xg<9vNap)l1>t~a=DsMw|$Ji7vD~sen9xpo~p7rAtfW*t|U2s@VcV`Vh|oYtD4WqLde&e!dXRl`D*NCvsOS8e;K96(9*rCjc?_B;6ek z8@AjJdP=X16pvPpC{X$iFSLslUo=2ecdg3PW=7FsR{Bm0n%|ZSL=eP<+VF-4feMnA zoWV4R>eHaYU}^N_)?M_>pMp2ucz7wqxO+44hxLYUUI9)**mj88czW$&ueF$ovw)K&XvZ01u=e*t#=ys)x> zS1#v+eUL-|9PZUSsvUR89~?>9j#?L<3fQe!xdUVMR$`InZU&(%^`3fvEB5J#TGdST zoG_g^JAf2V=Kn^H)vkKx=k^rt4WGN%Gb;irvvk|nQ^`2vfZHJ(_*!N2wTr~N1=76p zfmOg6B0mrkyiiMew*kF2CKSPH6%kt7`oxx&trI@7Sg8bp9>Du7<#)8}Y8(Q8V0oPIW1iXPXi#*oZbLs9YuN8sQXdUQ(`-X-sFyd>eZ*_hh|k2G}Upvxkju#56~%A8pBnu|QJoO@V{y zZ?ED{twK#{-a}McM*d2%cyqLl<9`+Ti?Wk?(`LElOM+=HPVdr|gp|W=V2PQvbVW`b ze~JJ2TnGISf)sf=b@{k77}i1Is$7)w`KXq;YsY=N>nFzHaLXxQ&+ek)|qm zwkt*7{!tuj8R4N)X4MCyX}gVtJXqUnj!oR@P?kALm;o*6xE;LKNHCrk#1ptV`1JQW zV&F}>47%lp2|5688ZCFDuqe&iE!5^$*nQ@{rUu-tapN)be3@#=@4ateW0fXVMz8@y zD0^H+<(ThsiiSG=pjki>3JTPrjW>&&z9j^|@suS?V5!lKq#ZQWE8G(~@iblB(DI^P zSnAh3=De&IgLH*aBgqOHMh>GI-lmnM>99y}j$Ene^wZ2kHr7tT)}wFo%bn`o729*w zH2Mk6HyME&C&8iMxwgG$c#gJ~H4=e|Fbul3luT)tsuz-4|0nD9{41SF+xd2@qudw| zE|aTXN+;~>1NV=C=&F_31uVDp7m^2-Tg2N4E>a}RK3B1c1-h#GTz>I^9RClF${ZG5 z>A@KSJpdzN?bS`TYS{^xuRg@gI*A2!kfPftxq@+fHRQ6@yj_!n3WNEb8J64}SlUIz zktwqtULG?o81_A^lk5l`jSb}(4vhYY z{#Pw%hs1@bbt_M`LC%V(u(cpHfHF`+B#F*9n}!@C(Fy8Ba~{!`243zHBZ_7a5-#203bJEvaa)>#cE~@sB%PY2lO36+w00!jV zlMYqGa;vW++WcohNWR66GSBbb?>QFpxfp8i5K`!%S-^8Ibs_ z5ArZ;19Qv?z4&iDNtsRPuf)lbG_U=*Q1cakM+b`uYNF<`-a_Kh0t~3v-P)PAomJz| z7nn9&Dj5njl()d_{E2k?eo$a(!YC3Qhi*q%A>YOQEnnE(bu;SG?=s+ZvAT|B)bKOY zjk!xL=D)!r5n!*jH&U2up9@vDN+lbk;!S`qkj>3VE9K!{;Zbw zgJEv%)qQ5+)2(e6a8z#m;kJLwWGF!5ru=ysD-Q>|nCy4yaQ*8z#}8Et$5y48XYGl# z42M4NCqI;_zwDQaX!d4MBy)Kq7ft3paPy2J)C`@xcfnNv$l^a>ri6^Mg2+QG49urm z4cDx6<2a{HU6kKv*2EQQOfXdKoVGe0DzRn+L@#V&4dsb>_sy}G7GjaUO*=Uc(S^!E zTTJw#*S!Y(snAFa^lVEu;Ii+LkD|S@u9%KhA%0}WJ>RJc182PtQecxI_a)(cw0~hF zkW+HO3j<=C%cKNm%Y{D#Z75X;IMHgTJ9b(>jUKtpl(9f87#NLXJpU@nI2(CQ&=)KEKkn)FyD=)5; zBiWna%DI4Nn1(y5|2B1)x-L!W!N)nUqlL~QA3DvT$j=0YVFYZ4r z-J9(%zZ_d2GEJwy3JoJ*-?DtB81qzJxzE!A%!nRWfBD+T0tpnDes(}IG0Bnjy1*zp z(RR<>1lFQBbXe3X-MAetB31e(WE%x=cI0YZ^SrFKGC*1+5Q;7z&qZ49cf?${*@d^$ zoRaWRwUo7`4%hwHuHr5pew^t+Y4FH;p+E9)#5H}8Xof=Xk;S3@0ghSGBQHMgKPM9W z$k$SW2=+7|dre3sKsE>5T$R(HXD6nwWMR=z_bI9361tsSd5d2DAKWpYmbZo-QK{l` z$c1Z#L<4hm)4Fz(ak4r)BC3TnL$KrSW7_>3+*VSsbKJ?XLGY@5>#_JRWM;al^+1Ni zFJLIAZ)Rb}vb~Ws;w8R*(=01>9w^ge}BQXcIuwa(zz5ST{zIa!s5P(ZNw}gWhfTKpjda#l|0_@cSB3Rn~Bch#v?cUlKM=kws3dJ)liWaoPd_{}n zhl~GGz>2jQ-3FN?Q`y9I9 zI`$hv2^Rl2fuTRU>ix6Hs;dygm99iyCV`xo!YNLezUJ4t6M=co{aTw`Yai1PTR7u` zaxhCwFt6gN1b~xw{njI_ocw0y^#1~$6=OE6Rdd2T-p#>ZApXrNIF{K0!?xQ#;Qv&Z znK3FsNN9Kg>;1RLwDEavlj?~>1rH-4Dp%g56Ir`y zHf7?t61snK+N-=cD8!R){s6Qw1?Urrrn+P=(>}eU3tNl z{W9T9JdfJ~ADRcz$=s8%N*q9OU?1!V`<&N2@zOBa5SW$NP1+k?xZwQ;{RR>r07DH( z{G1v%ypIdrFmpKatHhp0Mb>fdJ{0aWzzyoY%FK?>m@x8VEZBW~_TfyU;KsX?_~evX z14wYZyFCQ}19=foG{DoW#%im&5_ogo><9N?dLWIj&Y;7JC5>}YDpY?dF_TG ztcf^a_Zwhia=VDcYa#5f-vlFrG-egBRNg+C7H&SbmoLT3PNoQ_LJTfC zk#yo=p4#(eVNmNM$*iU}N#BrC4j{OHpcAuBZG-mYY zxd{UU>bMD*{@PQu-6nF9>$H_Qj`p4!CBt+hDNq2ZT$UgNZV!`dNy^W`?Hs)cyIL{O z)%OJ4&`de9YVtX0{(V7LPQ%o8#s5`LEaxc>-wD*LXRGO?@T9Hzsv~?01ULL=SL8K( zbk3OA)?Xll1kf$ivIk+$P8YGZzPmghhhfeV0mJ(UFZ%UtOUte~Rnf0Cct@o<9AcdO zP)mJ@6MDqz8B9V$OI43fHHQhPVS(75tlbJB2nmW}&jo;jo^ck)8s3Yk9NOOCCW0ow z>6kK26%g@i!8ka-xHVMasVCeDTpSbfTWo#oA)cs2R}Jcug~y{YuJey&Dv2I%E1l{t zc|q@r=_4V#Xl1p+zCk^g`7X#q)1t-GdW(1CndEJ{H9chJkzN@Jf=X&%CirtzexZTX z=Lt__GzN}0i9S2ZLh9xpF18iW3An3_8XzMRX;;Eyd}Z?=edUcKWi-8FZ+*?8dLgfkmoEyfNnc5TPApX`IA~ z$Dl9mhq%iI#9G?r6(&ypz$jIm=9rYhj2RulW#r*=Q#AMG;E|tg_BExUPzi; zJ@v=##m53tn95B^5SrcLf1NE9 ziK2p{!3=KMSn-%xq<7APsywYlf4wKs_zZ4Rewv{HzT$b*MUq0pr^^DSq3xx4ccP_E#NeIl!9K&DgVH@TRX?84h*4O!1o5_-B((wGbM zOHaXA9g?krC0a_ex@HS?( z11b@b&gL*J4#HemK+6QcLjZUr=Q1mNrED1*JYh#^>^J0t;Lz@!e81Ts=p_fv(usE7 zo!E=>NEGzKjZof?>pR4nSQyru`;U&TleNIQGR*#U!yST_FO&($t3i|P)$1f@jw+Katk z^EB_jZAW&m&+2S$yscPwj%zcg1>@Im(ZmWmd2m|5GNU#yZ$}m)&X@#mRrU%R)^pG0 zJp`}pKPfA{*|)*~d3mk4AVz356>NKh-4Ev_6vW45GQHlkcQVCZtzXzCx@-y3n%S|f zql9MI?u{0@CJKtLp=_pMcN-|YKWyhG%-PK|pFE73jpWsxS<5|nU?6+Jm8(PddnMYB zAY;_I+*&P2wOl?_mpX*JoBpdIE>XSB1v`q2GwDx>+f!rjlWje|;aCDS^lEPqJZ(Yf zqWgUS73+$jU%BF?mWRbXW_1NXU#X>{2X)U-GtyLVBYo0+1*rUQX8jstt_5YW;w+dy z85`66JImOEn2VXef4}!fcS~SiIqflv+KxZli7aV?8tPW^1XqxXcvvlQ{dx|7%FOO_ z8Z-6c>O5*G=8bffY2rw{^)UK&zl(Z2Ug`#-n-~r#e6xGQwKAF8OPo;ku5U2lDwLRZ zw3Vpp+C-cA#W_ptD1)g76Cwo@0qP)F022`w1qSStb_h)b!jV5Gy20|dieoHg$uAT7 zWTx*wVkK|7p=m2acf9U)$U}m&+pk;r6Dqf3ZKH2a1`LFnZ#} zu69_PE43{&g+5+JR>vRh=a}dK01dJ^P}#7yL6ji{^&G*ssu5{-F4$hlP9y{X?(#s8 zWWdu;9Tm8w!nW7{sl{VV^wu!WO-rq1UVuo8c9qnBr|=g?5(Hl*w{;soYfx8QE2XM$ zKpLxXjod$7caNk})<|0AzGy7fP+bKU#r7EC`#9k3Fo$;JVFf;Aeg-M3q(zNK@`kmB z5y2l)>m4(Bl*KSo=1%E~3#s-M^#g@Me>a~%ySOaL#Ht#L7vO_sYk4L1>@WuonZ()v z4womUkx~>QzY+kGtN5RYl0)UoFz5WhxnVl@Cn%JoJ@+o3WGciN8qII2CM*3rw^FJU z)Uy{#ptSlU4b>0ymKYw#m};XKk$r6?UMF}D*clwBOAilP-d9%?H_qfb7&!=r))(ZX zSlqb9>K7aXeuXp0eoag6vrur@7x|DrUgTNqk!wRHhuV(Eh?;bz&a#3_x}^v)Ev)Sa zxqm@^g;VK>Lq0`3soN%q?WqKq0W^*ZBc1__ppi5?!jIXzYqt*5Fd?0_*Oji(>)p@p z753PE=5JE^K<-g1Nt>h-(RL_0ee7VPJSqA=9U0d$6w)M5J=1@`}*4Q47d zcU$l{14#7;;orAMP-(MS#<66^2_G`=sJuR1&>OPy<;(Y$t;8T}!^5}Cho9};RRr^q z(-Q9RVa@CL@J*+_IeY-kNsxTFuyQE8 z!=wPVq*w_s%bp`Uf&zG=UTtgqQ*g2b{Gx5HDOsjKYX>zrL>c=#;cV4ifQOAu;Bskg zjIHlT*#%`hUMxvM7We>1za`4nem!=*Irg;G1fO+ME72`_?tXt5sq7WYfTdol)Ud^# z77>qCiC7T2q+Bu!2h{%_BUFpU6PgD@gJxb6Y;Wz%%gf>gh@C`K*V#45RCtT+lYjq7 zLT3Kh2tpoTQd9rMqB%KF=%dGSVgjF4Gb3YeRB+eqkfH}5nfEB2k^Vw9?gGOtT(#82 zRA*rheEQ_o(O2i18k?ZTGr=h=550|k5oIwxf7Uc$k<)M%Zy=P<@{{ z>iJmj2Min>u1EWIZs$;F^p+4?Xhu-i!0VwFg^`Vbz!Oq+B+gJ~L2efMgIGoHLeYc6 z14pUy00T){@6P;$==a0KcHk%~;^~A#Env#HJQ`gF=x!sxzoEEk4ecw$*_xuyAHoA_ zEHoZ)DW+D6uux9pu1tMJw)`^B2-or4agC$;%1os1)BmsE6yR}^(zq9;6e9jVix}z_ z50a?%Sf%dx0A2}`qiI8(?ty94QD-F<99UBw1{yuasj4i4jcqV50&*}7^Aq=?1lQh0 z*O993!_Wd9Ez{^jHV(u;Uw;Vf#t90p#_~gt9>Fj(VLnJWyPX1Ez-QSGM%F{%7gM$> zkom2o{CzZ%x|}3qPgUQm`lJM~s&a`kVujwDILvSRO7nX%>ae7Il~4P3$Y-X$$}odr z3u8CqwnW#gF_QAb0S0q_Fc)a9TtiR} zgP)?>MZHKWWW%N8jxoqE3Z!`rpGzA&YIR@WTog-KAL?=zW))qIW14yVJ zV2oBP-0H-_gaDSo$8A=81?v}U`ziEvLjpSpVECze7_ARu z*SrA3-=Fq?9ce{9Lu^1W{F=DL$jgNKUo<#kW zGzlL;xv(i%Yyy0HEQah+e`x&tk+}F4xJpoBt)aZ3xh)FNQ3%jKFX7YCd_{Fu6aF85 zLAU@(G*bQLO2Kk=D?5HK0{{n07!>=oFqDCE$5X7m73>LgKh3g8gcYIBr68U~o)~Caqs;&wm#^44KQb{` znhTNDoLOWHDljyNqI=u-FN$v?_VIXHKL#Gd$1+DZ8$N?Yp}sgI7v#p%_GQkTbd`pndH+LcAD@^z~ZI_F2N7)qX7j9IHi2G_^?36T3+kBA(~Rcsyt zs9s;JpGSPQysrsIwp*rAk)gC5Wj(NQVSNIJ2UHbBgNO8Lm%tCCF4Zk-^LPx`sW~kO zes-Gi#m5m>c}BblL>$rwgZhsm&~cH>weomp^Xda2&8%H+M+T6szjso|0uu;iZq*En zR9cYX^Z$wfQry|F@VBc_00000005p0s6qx+gFMEjh8TTYq?rLq^Z)<=5W%0^&X`om zbCp?743IF~Lh7r+WdmR$qU>cL3FF*N25TDShKXHiGPnj-IWnbPRfE7)sj2KLnr?%! z*Dc9ZrSTR#{JdQAB0f=9+4VY|!lrcp;tpc3MIeZ2Qe>fhq#`(y@_k41I^s4j;STC) zA>0fAqu@~?@tSvtyR8fRy`6FqKXr2#RU#p1{Ox^DCV1cDGS%M7Tys+|pY;%kj3@C$ zr4OYM{UT((su=?8Hr09iFjdH|9P3kP0<)zdlxOjUV8P)aGX4xDW7K-w-ekj^DQt`e zYA2Ao@j2$g`6EUXdLNuCo8x1&(VPA_u|@6j%43}O09fv2n-ho&0tR9U^P@{Lrd;WP zYr>^U{0nTOXL_dpV8<-hFR%H5AnJqSX(5VCZuhj{$?=-*$ou*Hv4jiZFniPUZHtw^qY~yfK zcUX?UHM(opT`qlQ(1@h#h8giKA*Rvs*okfSA9;P+3QCI*Gw#_rfPZzjK)daG{p>B) z*pT-@TY!BS-7HUpufFuS6g9D-;@rP4N`}V`@t06DkcErH(6q>PjjdBZN{4<9a_JI| z5-BXcpDE1``Av$X7UHAj{t2%8b?($NiSfrYwTR(++1f0<(pkyFx5zmS*HX&JuPi8J zDycYxM@zJ(I?u&P=U&Ew)<(gL$PlXhV=TLS%A^aRwL9uJyc>I?ySXq;SQ$j;`bW`h zYm=I-z-Eh=+)%UTf|BZ~bcHm1uViL{j5v*Z)0N8x#Mf~4WQWa1*2U1lJ0L5V($Rc{ zk_gG|)=ccb`E$_e&RD8L{DY2xU~I|I+kr6g=yC9lp?8d_&B;9PBow(-lc^=H8wg&^ zk)l~zHUZU2jEK!5%WE6y(iOEONw#9eco$f$lVTjdqr9Qsa}FWUCmIV0KNaQ*bgIgnXQa&xl z7yOobBgws8A!Nd*_{}%!M>w@@&G3=^u!_jEw<&I}7G8s$*M~QTvh()H0+iM^`LJ6p zm{26!)|w@CuXCZxHp4kb6j>$HkGFvmf@C4@JuU-@e@oYvL-R?^cTHb8ssE&|J3~bz zSjVwxF@UG+e)pxJ*QFLxzViU`r}pujKePTw5G|lbNfSL=-&;)Q&fpyr1djRnsL$2m zD7J8Ngx99Y-L6@*N3qmAobe)VK;2`iNOF@T9DansiY4dy3-wNZ7sjviLi;=*n z+ZxL@?P!JwcRC)*;}FB%O9_JXb9;yX7EY?`>+nH*x=#pWt~bn6F5%JYs~T`s`XC`c z8jhx+YGI=uSErfCUE86AB;DbNcxYw+DJa@vw0Q>x9*)bOrZ8AbO@*Dz!xH+S*IER> zb~%4oX+F3-yH*GR&ml6P-Y<5MjiF<9gD;IyKb%p1EU}lCs9(Nt?vlhq7(>{u3)C7h z=mqd*Rgn$RmS$f#>W5l@=m5bsj|Dj1V6!unp+=?9yM%}rRyXKs%H|7tk00000002&t z6BGit+yi^4tqI>mC>;>|T7lo`_%*mjO)Yb4Lt<+8kH`C|6MEq%bKOF#aJ8gsOq!?> z>#N$Ja8MyA#_?Z^L5NR^e;3zAKIBu^?8YJ0^Ehv942`!={hT{}mfFZbBT8a{gqF}^ zJCwmTqA9@vRqvb3; zXcI`n+bIyDW6(Tl+6@Rcv`?&)MzW10#`$cgtKjo*oVo5Mo)+FjVsesNf-4QPsnFCr zT1yMWTQy1dl+-o}7 zOt7d1SG*JW1?uwAot9O1RNJ9rgQm@)8LUay((M>5i*bryFrDIWd3p|;m0m`qC#E+4 zP|5uC?f_W%kyt-FSyap)i<{Ll5lr+fX4JHS>gMMzF4z z^t0y2<#OZaD5_#;>&y)ZLE#$FSQ(UdwOE7~d*1|dBh=JuOk5;p!r*Fgjns9l`9d)~ zLz9x=nzHw^*Bs>Q*P=J?pUKmCOyzzbN*S-u5=Ex=QKVfu042077HbH z5W7EWBwIFd@smu>Kc$DlXGYt1{=FQ}m%nw+Y3u-jPaNo2R#gK?^i5VbWPX;kw9o&soVUW5gqIeCshr{L46zN(2!-&LE4` zy|%c<&YC6Oz}t=S9yZd~gLw0q3%yU?gQkJX6)K;#+!t&OqrtY_Ja>ZP_|oR0KP`bT z4BI9WuwO7>h)_60fwH@fd03qRMY7oUOv+->A;x_ZvM;uhHL&?t^V~yCVRdr?$>i24 z#$r?dwnyNQ^cofOAUT4K#z~uq3U^CtkD#S5!ovqTMK3oO+?MV4Bxvif+PFJ=0g9s- z#IH2TpG3l@qdX9F4kqu?=Bdhk*@r~ca>EY_XsqA|;S=RM?cO-C`R)zVGfMC8kyDO9 zbh@bDSbTb^QInuR6xp0R03#p?9E@hi)d5#T@RA?C46Pq$+1;@Ac)tM^58zZhA%LF= zO2&E+7oO~@U@HMn$Vy^QlfWe?#7EavvI5OE&c>co8>75m))Q7JUz(bDy;+2};{=Z7 z+-e!Y*RzXRUl6wTs~XmHMAETF*+70H02d1EhJI9TJakUwBm`n3Z`q_*cG%HzZCZ3C zQ`HIc5k^MLlrNVVaoyMy3M5b*{N)%yo@^B=k(*7E*#1HZf&kMB{TtSL{sL>Fzg0?) zl^n6s_~0a5y(BG_({Q}-Wyv|rlHFsh_;6v4O%Qz60*8dsB;o&@)w?^DQInZpBtud@ zDN9b-sN1gA03$jPL@=EMTm5>Cido?Je-!y7$Z4VNhPm3`QM={7>$EO8^Gb))4tr{p z!kC(0(9gG!?ZtU{TJkmqce{`BWWy0)YNbC!K5mj8%UnE1AE|w#0Z-PVBGsU(yPsn) zaa2n1DtA5tsNg`_0oK7e&X0$=7fS`B^C+kb_sygihEy##$Ycy))(@X08he(6MJO#i zysWBi$};p|3h%vX6|&^V0I!9H)30wGTv!yYs{^rr*c+2t$u@X3aFTy*r&rL(D9=#& zTqYy1Pt#;RBlE|&Q#}QN3d-?gyD@kqgkDPAR|X5S2}#nKQec^(+u!E!*Wp(9tz{g8 z8S5?%#Z3E;Av4dFChq)Ovr8BnV7dRQQuQ0mm^z(UJ36tJXvsp)S)-G&O-8B+MEnt<4uVHk)PamL*5i_gyD%p#Yi zASmAE7Z`Uk2crb}s2%f-i0hjLCPpzvPDUKM*XHckFSb>lDC_*8$z?S7Mmq31+0>&u zrBBm1F&y;ZXO-FeqJ5|6(V~<(!`d~})7l{s?n!ogJYA?gTgkLvg2*rKF=&rHd0I?u z(v+@9a2`STO-NwC3r86A8`VK93oJ;*{C%tm;DaqmkkttdKf+aZ8Rm^rvAeq<_^ha)4-(|ckuo4mSRLe6snJv!Fe;^jJ0-<04;hpyS5!tEd}4U1Wqp z&)%s@^Or}sgQud@)_c7jog`?*;V9kgcVU^N8^0Xb*%^A@bK z;IAxGWwqM$6Q&WGNG@M?V3Z#nIF)vF@)H$+Jlr zEy|tCO1^u`)G9?w0Cm=+_MG?91B};;?-Q4U32596Rru@VEy!_UUVS%?I;!6Cc;e1N zV)OBF+#6%ZWAK<*(>{&v=iMp?G{8^_(YxdW5qD(1Cd7WBqws^ep{|I2@qY3ZjWqSu z|E{i;cMTOxs?6yR6lPV^XFvll;MM2N00@;Q!V0pg;8W5&GU8Wn$SYM5`7SK}Z>n4` z)~G!BS>)v+lG}H7AN~$?U(3o&-}bjD#(e(=$2|7-Fj;zV)l0IAzS3Z_=52}q$Nz`V zaE2)u3&HtG9S+DRwF$V5OD^d z4|oh|bH&hTfXg#3bK??6<6$3+mRdOmek~(yIVC8G*NkdcF%N$iwyfLVTJmdmaf*;D zV)QKT88~jTM3dtlUe=SsD{oikn6#(fu43_v$3-7KqpJ24QRkB_jWaqbIvgO@#@@}ynSqP1jD+DNfvWP7zWQ5BRG z1g5|i>Y>yxxIp?Tsq%742LBuaNc&4L&WD;WnR$_mbnt5n%r!a*AltVyp0q3pJp@a~RkeYmtV~ zK@hHO2SPrJb89OJB@NUenVFD`FS8ZQa)ptyorMjHu<4Q}RIZP|m01Oa=y!Wmf;sw0^ za&)f%lG#3*QciVk@Ktma_`IHtJuwGzoT7+Ga>5is5h}%wDQ-Xj36D1mXgEREEcFY9 zelMjCRM@sfLnRNg5*4R4ue;GKZ)`JPV^UEn;5z)Mf&iqrr((O{#`|s=3Z>q;v<#4T zIPf{xSYRq%6l%mskBjbs;=)J#m5T$+i4$QpDf~D8T^vO=Hcl%q$=z?PENL%Iq;V8J zV9hN1CbPuzNd*J~D%*Z38q7M8_y^+kG%exTcvq{SCqPh`4m&sf=Y8-WY`9!!UX9SN zkTlfBGy)<_r5kU1LLI<@UX^Ajn91z0AwY)=zWPBL^xlV7vA{^X(YWSt6@ts|6R8r< zyNek5t6gan|Cw5n)`LtRagd4ScNQpDVsPt1Rp2J%=3j_{-foUm(F)qhC|G`SSTt1$ zo>-dx1aa828)3?=S>u1YObH@=Mwg97lNxb*3TfN!W;M!GZ0J%ZnF1@ouY42KaaqYo z-3O|bP=ZMCFwQb!5K9&%F4Nvj0yg3t`04eIAh6NYzgm~h8k23Z^7(l_^~e-(V968b z>8byHELCOL${KG3tkQ+No}=Pre#^t6%-e*b=NszP4>y9&br;zn4yHbku=D(q#6{RMpnQt3VG~|$y#c+pZNu}17TRT zu&jvDEt3F2K)$~}*BbJ+aab$g$#s+Ph=3q(-zeJgGMbq+HP6&VZeVKtzVsMZ?V03T$HC_eh79)6->t4R|>@T?6<;|B+z?X5u|Q{ zlyMe|byFdV0g(*Oy@ud4>om(oOjW9!HFRL2pYlI+hu7YH2@N8ni>+!-tR=M;gpX04 zX8uQn6QcTA1qVV>K}2sZZy_Yy961qbv*Wz3>X3nOOoFO5=!L@|F++AF94cu0qpP=v zl5qXEwU4w#6Hj+AAfJ;yRmXHuQX_JTC4R$99Qs>Q+To4BhC|q&;yo|N!2AW8DgEhi ztkZKkhco@MW#xy%GKohQUTp|34Z36gg&vt-QQ3N0lWoLSkgIT#LY1=zfH%jQQF1%! zenNqZ%uQIpUnmQPeI=~LB&J0vR&3}SjB!k6ywHIXOB`uv=El{u~VinVQ61jtV7sMfe7Z^x`%-z=Py=gPza+e|#u43t;ywO!yP zfX;9va4U(RZxt!YYeg$o zWSVpZi83j^p886^&0hmOCGOkVLJg~lTkeadGljUDMD}w=4LvCAzn&V#)NB^g5JgMB zkNoQ3@%;e4lOa`Od&4}D?IRyLsY;vcoSP4pd+f1}d%owIxqH8W^%Bk9Sle!6%uo0EOYB8Xi{ubu|j zB*uIq3&hEOKSxmSa{OYyR$IR7E~b*$3I|0O@PCgCJSKVOUpWrMpOKJ+000004FNdqzE=+0zgbbr@y_4HgdsQp00000Y1u#ykuGc@9?BhM z#{jzNP8BI5<*m#AklW|dJtq5b6ib6}QgG>fu)qBQXH#)DPWYM1?XL7-`~+gm>Z!D-;uy|m~hUPQ<;vxpx!XddDC+!T&Q`0=*V_$(%Ll^AlmSfAuZ zFNljrW?+Q49V0e_vZMn+P&#UW;;&t9bF3JjjCkYko-L7n^iC%6M%_FrDj=Bb*AVyk ze6oEmX;>%!3D-(Nn@9s68hO&AZV1TIdd1zdBHE(?q|u~DB$=&Oi@x|X$$v#6Z%TEW z7f-sWenI;M=FB5vTs6a2k{6KVDLlrwwql$@Z8C+1-Sj$QCNXQomlpJfonQR z1l?EJjQcl>N>M^lY`N-fr*7Ci5 zVRS?IN4t>kkobd~p8z&-i-sP1VMZsm$nTFtlCKw>gTW?5Cn8RN>ZCqKVEEi}ARPnx zG??LWsyxL@4(+AUG-p}>>l7@%Qid4bKRfQxOc90ZsfKj0qGFG{ca-ubub8V)kkYgr z7fH`5Oke{cTl~7)Z(ZWiJBoaE`|Wle{E+P)yX5C8!L-p$RpNL)*7ie3KIS?jqG$mV z$IIM9GYR*kNl}jkXAE*VR?SjQeh90Cp29xAJb@pH~>jGEFHYp0A;yGmg4XE<3q=9MLJq zcwZwbXv|a`o$Aw`kaA{93W~?WMH6Zg!0neSTqN|foF$L+cm$iP8He_bsR$QCB$#co zUgfwESL~1@QPA+hHGmi*1OV=v2o1{0(A&gCw^0M0IeBVrIb#DGy9OOz&AaDGR2U6;%OymlL+ zRds!Fh1lURs<)GHgI5QIa)7K`Gmw1pQ1fc;L!f68x^Wy#f^;C3@4G8ToetO{CK)A* zpIr4w`O>A>M;oupHLr_W)^80PlNG$?i&y&rDx)vJp>lo;s#B0Mvvb(dr z&Djp3bCS2-ZeK6uYf$brX|kO>wrNqf5uIutTwSvC)}G*`O$x-hFe_P3(+EAeIb}??o_F z5ptdHCvcJDHZ|kt2ZjrZ?G5meWh!fND{-e4Yfypfk6&%Nd6uf#a^Df+unU~^oh!lG zV#^X@5%&BCuS5-Ho24v5!=;JFYfQJ8C-fK)DmGj7uiM105W%}~vwxQ9ltxdbj?T+d zB&53kv}-ablE(3Ft7CpKbL;^84c>g&t4~^_0PkWP)RwLpMhFk#J0SCvC(7-(7+DNv zjxaQDbgnKf_KJvYC%x=!gHqAbWwMrPs6G`SUCYj2m+G9C-hRsIHsuY+;|2@14u|otGg|$*Hm1Wj{ zSQ8awqT?H3%!gsl_~;MhOh98OOK<7MMXy3@bhOOsZl4Nj$DeY7%RL>VfR=~)(um!$ zlYLdOuaV{p{ppq+PvFbuQuEOyrcVa@{_re0cgP;{+4Vc{^^XEGs60lb&`+dwjpIfO z@VE-&191$Cg62)XL1NJ_u_F$4kNy(U0p?MhJOV(0^vrWiEG;+_=wznZ zd(pJgi+;{pdGB}YsRa&eE@$C=;K)Y5N~+?WBGCZ5A9;-}+SfO+7~O_w4D%}GpA;i= zX@F4r_`d_abQ?^{)vUH>=qImu-lJ$7BHJt-IJQ0z3(9qr9|SemRsTBt=eZ~~1U?x} z)O;=ZByhXHOp2p{QLT7QiMj*KPgSkEL5G}V|lgiKB$j`OKt`b9qB1&lKy23#r@CsJw17Ju4MO-x%N{UIL%Z;(cT^okt4w*9a=OM3qQU@*ifN@^W1Mx{GAyJsRnZ6*Tlmq5 zoh-9DsZ!i^LJNKB*iUH$SZg6W=@XBp`~$O8Ea%`qt>K7F4_nj)=zv7u?VOIYehoY@ zBQJVxtHV&ETIZw<(*YMcoJP%Q6TUS6XV#SJ6Kmb|$o*NtD(D+v%|xtb;g%PxRfifN zLH?LAR;T=T(sT&U*Mu=gy%kCf5C$ zenQ>CxPL$Z9=+C-acz;KB=OqsoeX^hqI8cRsx^PInq0=jOzTOqoNsa{{ZrBR^tXo^ z{w1D;7zS-^Yifeg5!@}&Wn8JSI-cpO@qsAr`c>8Y0(tZ23*EFojZ*BN#LCC95JwmV z;4NxZX;$2T;=1V3c!cWJ2krn793UbcK_^Z|o!?!Y`!v4Z^g(W?%DN9+F1-@7Nu+#p zsiidd?2FO~wNFAlD}X^=H|r*CrY971MC-Yw%#)k8_EU{GZSuRsfMe)E5ppl*5A zZ_bfHOPYj4qR6Pb&tBTD=hzNJ08$l**^?-*m1)`Mv_=T2ZkGr8KgduA(tK3$;J zz+`sYI|xrBeAu{T83+u^Q1b-}2=Hl78nJ4bculfjn-c-Vw}adoX+iFvH!Ju8l7v%L zsKUhu_n$6<=^0G(JY-nv9 zfc>i3@ZU*o@^bzPuMB(@+wws7!H+I7&p+a8n<->#E3&9MnpI4W%p>}k1{ z7sTpWMJ{@N&eIx9P7nA36WskD8nC!kGv}rHA`X1n*B=O-K6SS+ip44dF7Hwo0peJ8dTi{dCDG15k6bJr`}PAGFH#M zX+&69tyFyg`0p~t=Og{F;X_Y4&MLA&ggaT{acFCOYr9q6=YNs|TG6fx2kqY&=HW{# z!0Yq_{zE#|i4|J^gahuWd&?PBrhkZsRr&NOpBPxHLeKurlBzezXTYMlroUNRBTp#f zhG8z!yL##pRr$hye0$zd1o$>gc%;lTDe6q;#vT4|!Dx9D{k&E1HPZqU; z{7r5>oo1caK6*gA0F;MzRe>MZZMuGWn>yYE9Z`m*areC2kHRb8P!D8C_99ZF20=y1 zS{Pc}>%KiHB-cn4&&hH_y&p$0j@aE4h1IdDRJAW5|Dd< z1v?mid(<|rd6cToTKj4=zxn01s!IpAC)X0o?Q`~`quqNWqr-l9=R#It^-TLX_#AIX zy9M8Qh+UHjU9`8O?g>guv~eS3!wx=0RHM%M{TOz+*#C4yob3adIMd`fID*A&F93mQ0Lx*Hg=32k z$@41W4A6Abs^Cn}xaTT@M^6DiLaU!DBj&}KoHkkkvV3b;dWw?rwe#0X06;A5tBF;n z7b&{Xs1f(8>L*5!m;joe>KYkJi0!*eN|#l}uLlfX_MLuuOPAYOPhhd;4oUyJ83Cr2 z9)y*qwdmuD3q9ieEK^8q8@!OXdeK&0g7LRwVWGi+o|;#CZi1Ll+ocxSK6Dozi;c;H zD8D;S9Mx|o%KG1RGd)m6$-EYNqmw$IBCV*&sT~=oreE$x+<4=XLQuJ=WcO&!t>+9( z<`N1*1T0-Ge7F9@1t(_YygV_XJEH88Oh!erBvF3T?A}>r+XVuFe!ofQ{EnAZpR&na|OI6evTD*w^r=4W-qv=G^`0u^$E=g z52~8yvU{8}uJ*36VRasU%pIPIxd|}l+7t2C9BRK+k~bW37oYgzcEc1v021|g`{fn= z`fru=qs82V(UcNV*NyLX!p`AgBS86t+x0WP(moVAiBK5{V%5hL7(*Xpo23H z`c^$NGr{6GCCv<6%62#%vad3UH$Q!9 z^<;W8M@hOF9}E@qs_8{lfU~8Y|F|+ap_19ycVoMFCClYxBd(Pp{S3?hdrM_BKY9i* zTsXh54K`L>6ukQ?Oy@|@(&Ei`3EmVb)RNA6qF|Uy0+qf18iqM6`mVAYW+)1L4C3&T z^L2O!R`R8fw1T%8ehuvGNm9?1pyy}x*QxNMr;T!{h-=fimV;Qp=CVhuqWNwv1m(pz zzHMK3X3$NmuGkJ70T76|p`f*2#sCqv{vnaS%u!A$?XuJJ@TKAGqg{UhCdde# zowjqg?qal@*+j$W5Nh^ePUMf_RudyOU>|VW04jB3Y(_^Im^hliCdz~I%BMK5mV7;G z5t*ILw^Zd^Cm4i6bBL?KIw7ae^Xs`z*HH;h0P;m6#x{K?Aw)kUfN%gEiSypTw0Sdp zsy$YtDF)wlY%5N@uuC~880ZS9ES>{9iHgj~9}(hTPPF4M|J#~CnEcf22bLjIa_!~S z#j3sao&DMn+jK&gVrky+1&!iihACWII_p;UwR>We#RD(r$($lKzG;3p~7$6Bi6Vst+=2Z-0BB2T(;iZ^Q zi+D^|np>AcB;sU*kJ-odK#eVY-49lSi=}UjvC+Mm zXrZ>ezhQlwP2(hv758Q3_q#J;AAz!ZD6*-as`@Z*xP58pDO$qVXYBaa7SxnDkYWJw z(3#RoPuOMj0P;2=NL5w=g1w8|c)PxGG)W-T9yY7XRkU5{V84!Up~tYE6S)A3(sOb? zDFsn57u+O`{T?u|eRil$oB)9HDXiF+-hhrF7)>lEYA@cDIkEhrkr6vS%UeRD%DY@# zV9OS$JkJS;Syy4PB(>iO39iy+w&K4Ifxr?krdu|#Px$eG;_x3vmINFhz3#5Xf&2BX zRWEbuGm2*&UvAi(q^W)I00DVa{xP9c z#yV1s#h$4XPG=ZSn9|3HgEF#<0O?^uCFc+dndSEo)&7OPD`p}-kpUgivp6X6MJ=lZ zf$RR5!g-=6(xl<#g*L+crZct5pE+L%clx_QDO>SHf^-}~D~bgvXljTW!z_q1O3s`G ztonvpS(3VfDGgM^E^_0V;shP{$CD<9<(Kkv1Y@}Ht~AZF0^h`E?~xnJWy+J!me54K z@aO$5rNBdo{86%=eVr}@cOrwOi=c5F%_)GAcQ1>IL3*)Zb{7BTiGz~bzGCsH{e`)$ zb&C+}$6F?LAdfq)ELR;xKn(Xd&N;y2CB@8uyO2}MnG#7JN3_UHC^QFqix^Nm=&&*T z#djW%3-c?f(_N`qM8B18|4#ZTU&7+%JtsIYzMO%p!ME>bnf+Yzi&*>=EVC&bU1{?w zDj^cjnE3MkS(tO?Sh%07{KCbIJGScg1ys6}upsx$o)yms6^_Ba4iMJW8P=~qFym@H z>iz(H)x+N9p~Lhz+U^@lr$t%R^(7x{QpRpGqDD;u-?XWu^4&~Ycm~ai(9z?(H>*oM zG;qWm6cRIRnHDP``(Dqyg!e&)2Yya;;01cgaqnKH;R}1@NTfb z@<}YFhJmKtO+}h%rk{#=#PjeSK zwUpi&22PbH7iw-mwq5iuS7D2e`u5+C6n>)~>cG`5$nc0LxNgcZN5-Cg<8IAf{C)N^ zQIYIK1?;gsdq}5f3NL3|_DuTm*m)iLOu}nf9|v-nC{L-Ek7KPhw0M)I_Q*ro&g)~{ z2{KbTTWGnN5`wWjhuKzVnTwgt%j|A`SR-K#;PnVokG#RK0`>a`IAf1DIx+!&55cSj z^pgF!(mroV<9t-MuB*KX-ZVEAbnye<>MGzQC}>_M!q34|82TGUF;gB2BhlM}g}Jn( zBj1YsewyJ^^w4euUz7>rS5$7wl+~lJLI;5*n5Tw{@&%4^ytd}k>x@Z&o`FzY9eC+9 zv4KFAqW*V>=q2afE;ltB9ZYz>Q`H^eKhMZD)Etlc!0_$fT|VZe$_?mx+6EOG%I#BK zI6>u)0acX-GF%7PK{HkQQ`fGB90Ym&_S8im@{n&G5^z~rrO~v+mgC2Y2%fdzsD_eW zJl@uoz+mCF;vsTp5sQLWsSkD0%L*ab*x#XQ^G2MI%Q9QY2dYe_*lbGgp%6ApCZ$8A ze`9~l&Lc2&-xEAuuQEZVpS8`BweZD`T$uCC&UsM&THMLpSEk>8E@B>5C%{=bngDOW z3}R@>#*L5)2D@f@qHlYJ(F_msgvJgeV1E`7>N)ob53qHevy4Fkg>R^iSlU?mF=acQ z(vP87RTu3_wC+=KNT@&%@q5aw*RK}$nT_L9R?>RS<@O!oP3)Xu*EI^oQnet zwU+Vqlz!VKw)osZ0&oSc$eJow5gu?H!Ka?ec$u!enuTpOq0OymF5cS~MuzQcx;4tf z;zT^<;1v;D|F!qnfB;PZyB12OMkXo3O}&W*1Ri2af3cbNIb6^L^5Tb+IPG7!=!01( z8i`=i@JCL=r{AV$ro)HGS8Z($fiW8K43Rf@yeZt@{(kmNFbjG*$pXT?77TZ|*g{l6 zychENEjPOC9OE}th){%0i3bAOV3%|{B~qxiik*?vegpL)B@Krl=dRwQxy-;d7T8vv z)8H>_<>Ec@HNA%i&Iu&zFFg&1|D9EZQ_9xX5%3$xMyOGv7{0hiojC}MASrj9qCP?f zG26F0@(C%NZS;%kQdaUo|Ma&TQmZMP@{1M$5fLVq)2=Y3vvZ>)a9lUpg7WA<&dE}3pqhB7~lo@wZS4hNEf zQB(d2YO^7Vc36-jUk7z`}uvEW3;dF?YrnMWpJE;aT*H+G^ zqp}r7O`Caf1iUFqi*C6qsYy0b+RI6^ldWN8`Uk%8MvNeR$i!b{m38JZFBs31leW1+ zqZ}>HH_*XY<(*m}&ML1PK@(tK&vUHV-qm*PMxwz^a3F9OE~4*=p_29h04Ch*L}B{l zvp}~0d*NB+4p^=f5-PXthS0SigRh+y0008x=>eBiKxA#Z?{?b+s)dJ>S^&ec;q93P zWi%j-w5bPtn>;Hc8`JBJu+1dKNAd{5cblZSv%L1t zXQv{7CLPH1xc~@>QR?#=%DEPxG(T({ko;`%&4q_nf#GB9bQXXv)b@ z{oEK$`5N>y=;e^tcrOwQIM^|FU(!Yub0m&IV^&9NBM;GNP0IX}QxW`u47o?=vi`_^ zeZ%wuorLxU*>*4Y>J#tv4%0z8PhD;Pwc>roUJK@V@a}!rz?g~_A;8U_94D%WpBBVX z{Xbsqh4#*e#N~d5@JXw|6>D_>0K}DsJ=)ZN-K#th?7q`|Eu{j$=+^06PF>U`sF+jg zdreSw9(xqhOYU^x@TbjcF^g;R+@Iir;q)zUlU;c8`wjYcSmmvLxn`~g*jQTfH4`_@ zlq$s)qcPgJL)>nVG{G%lr@vqaYVk%3oTGIgJmZk}Tk-w${ zSw{%W0`~TA*&y3mya%i5huVK0(w!Wc{KjStf?Y{e%6+Nll1`86Q<_EQxQhpBL~VC4 zp{O*N0gaOLlEIhj;}SKeMh z{eR_#=Fz2#0en{paaVCqIT&C=DeJW0^YS9E9btT(_vP8;G7`2(6ZRTpHKqA3)YCHY z&^mFR!5@_Lh{8Qs~Rp( z`uoq{(bWT8)y?wnfiYRaJ*J+<@}&tOu?{;n*Ee|d)~>^-XFJN)?eY);-26*Eze_+c zlzs{S#(A9kYkC+zHcT_xjQK=OmyME>E65VdHtxo*GEF6_6c znC45c7uJ4RTRFL=m?oiQTX}VEHt+l#ER32-+uf~I`hPyt>fJC_Y>#I*i1+Zu#zE9c z`wYYJlyYgn{-~#`kN$WT66!e(1eh1=TYr-T@d?oDY_Zp}unA9G<*?I#z~4FN&dWk_ zPFsL~=0d4h3eyd~o*1ytVLdL36lDMen}xt|2wPs3ujHS<(l0LILJDrZfT_Xlo#iKr z&zZ6E{^6rWP;qFO#W04d&y6Fn?GRl9+*e*} zJr3{Cnd%9UY(dr=bcolg1=jf!NyaeSLi?(<98?|(P92p;2DF@>X9|RUl4|;)$035s ziyYoHtOK2hD3(N|pIbtzV{X3>wZ%%|*sG{Kk|TMko;NNk1;$WqOA_s!M76oXOwZYp z9i~vyfFC1x-5X~=Ay4tmAVI0->f)%|KuH^g)oK>n{?Z3N-PbE=JyF*mlYis5q`+xa zCb@X=Aizo^$n_?+AbUb~STL>MJDpuMl>@m}7|2eT5Nl@3@&PKHWi=i#auyTi!wPC7 zskoDUhUoT|#t{P0snOzwr*245AM-)t1w#ry9qG~=xqCM43Df15o5dR z@FsNg(rnk!<(jIkwHb%{GaTK?N;O68D-SoHiOHUykQK8~Y&VB|g^laHfN;DGGDz3Z zTo%sco)G@kpslZe!f}ObfpW^&dx#`$BV#6KTN%sz)z>Q8_I=(}Mi9{@o>L^lmd~;9 z{s!yVrje+j8-Lc*FH`I%cSXRex^4bfOHuUYO5?$nZ}$?W1np(?OhsHxv+2B(E`cPn zD$G#>$b}yMK!oY??P~V`00AFZXEf|+Z~y=R0GUoFqaxKL|H`yzi%x3Z8_cHh?kQbS%5b;4Kc z6Zi14i42s-F$3=ojT2y^4~pf>t)Zu=OE>*A!%WwUZ-qMv13BhKg3ETffBnJF4M?m- z&g7G+Q!ye4?bsH+eh7RD>@5fXwY|T#@C)=$fYa%H#KRC#_BpH@<~Ij!W3METU(+EP zc2MooZ9itGQ`>ac9%eWJa3~4q)G3m)+JeScsZ(&~ROXf|ImiNg0N=M}b#RvDA(9mz z%i-wGWbE`G1tS!b!e8^dLv`3MfYS{PlLuvE0@o>Ka0+O)lnhhHlrmI?R5kdaJ#?fi z4`4A+d=x{VpsTs&`*^kx63vAV2PW`1-gi*z1)%muQm<_|jCL_mg#je)_UU-JaWBd2 zwf@j|?E2A9Y9i)FPnc$!hit=d> zB_0HT(NN{m`Pfjg%{`h<+gjg512E50Y*R&Ob1aLtujgGcaT0Cj@LA5H{bE5rQL$!z z6OZZVWFwFUIF)p(V9y?ZzufbK(zYkh_-&kh9Sdou6kO|5{mK_iJU4|7_sWi@ir8zZ zVsEdrE61NjFbQNgXY72cnLkBHF+j{Q&=+WX+h3J0(Rvm1^u}-+^ftE|Ps>${T|)p3 z8%!)RI=Pt~Se|9enoLu8T8BdEgP@uDhk16|FJsA&p~Da9IjLMql}Agoa>pC(uN42?6r})Ap$#v)&Kj+uN+pAa~b8m50dVzvlq!LsikGaUt2B zy56x(M4sVtuJU|Jf|YPu+s@#XzS|EhmO+XpUIBfG?v`1YKlzR7=dqKZNp5-cWV=sO zF&T9hP6KUFE+Kab*8ax1=dgh=Un7*p+XCGy8eG|lJO@Un9nlm`~mfv=1aW?f~*PR zBV;L`6tAZcPxd*Z?PXv#w7bmj1}P}aQO?sMb2g&iGa0;LBdRU5}}uFieokEV3OWFBNcwFQ6$1g;4^K ztm``gO5#}pww{t^jyD(vy(Lo#*>a=T)~-R5GeFJBBLCp{|Da4k5*`ySp z3YTp;D9B}bz<;q(Eeb1$ZJQ%M8e{iu9pl@fcQx^s@@9f^dxB z7ra{sH~u^X&?Nm6rtug9J&4Aajn0a&0009K=&G;+FpV?P6u>jt14Y`Mw?F^@0000X zP^(J)zCvqAzZKE%e4J(E1kyIA#O<};wqZyyfk4q~NRsulP=iNv_|ZMBtOSMC-W0VS znbM2Xh%+_?lPN95K79SyQW0n_VH|1kt6`?0>+x2dD%dp;`OUHP0dQ+)+vwEFUU3?( zMxG?DXzph?9T8*FIr2JhNLJKv#)~7_F>?n=ll!k-oouUJH2!tJz4%LYj3MA!HJ->^+JL%%eJ>>%&UDUPjk-MeGb!6Q18UPZe0 zB!vUP$B)v3A%VPr9>DcykE!T!y9e@{$T6CWFr+QflnOoHmwm1|ng8TYX&2flQ4(?t zrZ4d?eySfsfnx+Vc3CB#k_ynJMDnw=d;`uwo4JF<2T{5T@}N%oB+`QS1f7jP(`wUf z8&@T+wsW|3Y;LTv0mFa4 zU4^23TO94A#ka2Z4fxBFU3T*dp?l0}VE5+sXGEq6UNl(|@X;srx$H*~v4ImT?|5Mo z5yGGAv+#(Ox&OB0BKY^RUz=d|@1&FZ?NC5lf^R2bg~r_FF5*NhN7lBe>uctXt`2Lv zJ4;mW!<$AEevfoJv= zh_PNqV^7aBl3-z^l@JIfGXsDXZ|Ky~?PqGI0GrCnY`MhII1U8875ZLIJ_gxIrn`VJ zS)Fp?SK!3!2-oE-QLpMWje?A0n(yM$1v%}7vv=qXNt`ie2y}#k2+Q1J-qiC}o}4lm zfr}%nLCL3pPsmSRf#<7Y$8T1{Fwm$bNAWXsZ8BV=a!M+FFpJqX+HeO)qmaK#FSiz4 zD@(Velt8SEae*~qx_+`cqG_$eu7L-I#M2PT*FiK$_VxORj5NzjWQne7;eq+Y9K)Dr ziUV?OM)y=X9Ji|KN#@Px)bl5!tb59k05{=&bcREiQA+(@Uz3*`kmD#*GBP9g11!8jBOLa7z zZ&V5Q!D}7+lfetkP5n+9zkrz|wRC^!yeWK*SY_hSTxt+(Lk$NO8gLtFSYwV`?2D&| zhEg~tO|nu+D81jL9lyM6w}L5W-IfYci$L~gQCdTF=dVNT%Tq}(n&Vbb-0k~7jlCC; zv2tJdi*0gX0&Ba_UcC9C2M_UrQ04q!mzHyHL^rLm*ADMqA#TpNJ^Jh8_Tju1F3@?JM3g>%K`7ew%T<ddfZ!>9QPMHhjXCl^ndJJRvxsBlp5I2l>!*4TsnM^WcAE@ z@Bjd+NS1iq=d~=G8BQCcEK9gg9>I^uqo>q{iMPR2NZdu~gmkvB0#9g(^C~4*=_sde z>emdd8Ey4eo9zb@+iHp4$bST=%gL5;w%2=19r+OzO*XzJDMUvJymX>*Zl<&*gutcJ zo?wIQ){g3?v4$M5evT*Cg9W92v8%_+fUw&3gwi1u1BI}rHM~0Grw!k>PpTg33=dn| zqfAFI0_T9XzZ#&Giy-2A56}&`gK_qt-_NYhmM77!28SmB*;S{qkcpP84AvH$MEQOd z*qW2KpD_svaRHFw4Y~`tTG8t!gC&ikrt~fOF0m{-)snil`^q&BZLSw+SIRWgoOGNT6M_qEK(?OQw5QiqDngE{?FbMBMXl zLpJOfi`4PfF+Kh)lWox5nxJxalH!E4q?EGKmgKEQ4l^h&*F)gE0 zduUS{Ygo3Y31CoZrp}mHr%k%(<|h{${BMy?YBe%SpJ!Vn*RJlDKRt6lmb#` z6Pun3?Fr|Ns6?}L9{(BzIijP#bhQ8EpzjNRo47<41r6!H&Y}C2ol4d034{d^j&fr#;8BX#h(l3$_s_8!u$8w1hW|-Fe(4U_JXU0;##{XSY`dQ}ue$l% zd2`(AXX}Vl65mo!LjzH2o}zGC4^y8FX1RXM;zg^J~d_b{UEN`OrXe)!SR#On0KTviN;>(@d8&Kvkqo zMZFFXG?*DtHqQC*YIN3@6h4KiQy14Lh`p%Gl$a;%%@LVIfK_tyu(JN%`Zv&Za2igP z*n3p}w7k;N3bWWp^1%Q%$xq;K6)rb-AD?ZhXEwKQd z{O<9K6x?Q>%s}EKr55C5B>fFj^p7%T-re6S2s7hEP`y}>9sqIm7iJBLhX%MyFlI(` zK`>Nf))?PiKtFb~cB3f-c-Py*<<+&~vazFsRB zhE7Br4f2l1y{w(f&bZ!6bhRK|54?O6z;^FkrGcpnbpFB~nML{Mb6{(5+gChqsO4k5 zbG7COXNGbDbhBX|eja?@{q72#2eTfO0?Y+WlgtzB&Y~iWjJh~RuPosALkvwZ$nMFw zsH3>U_d=Dub(+5`-67alcwRbZD8znKy~Cz{HKkPv>AtD4oYdC%RMf>br{KtQf08kx zrMQ3u9C&uzoVe2*FJ;qz85KizS5Eu#ugE#Qs{j-7E;%Hzrf>}Y(I3F8htH%{h(CS^VXGrQU%x|zO zhu?3(j22Pe@GvxS)oWewQ2*dOtQVC1ynz9aF~v%jXz3QjMBxca(fntIp4Yfx__SdJ zAe?KPsI}xng})CEmRopLQmTWCah(U)^S@K^PJ5WegcedQ2moE zGJX)Y(FFt`9cOxUI|9)bV&Vl!-k?0dXob(R@Vbf{AFm$UVd#jt2-bmQ+UvNC8)5qg52{+zUiLE zua1Ux;XsU?TKuWF9ZW})WrWHSK zt9v+omjW(7BJ_dLW{68B(g;Hj6eb&{DTk?ETu*OTFN`6?k&Pm0aH1+dT+!N3Lay@B zCL>BJuL$V0kfNF#&P=#}u8STo`Io70PHVW<-62S-wo|4tYl6%XpYgr%?VSqcH{!+! zK<8o!OrPpgSLqL1?GCwHWVyLSpT@rzMCZL_Hi1&827++}NEJ+f3e*Z7RINBdgIelz zqXW+!CfNj+&@X(b9=9itSA;TF+&+R0lgRlsX>G21*8d;yMah95QsL;O9VQ)uOj~a%c56@MboQ!!=ANi{s;NU*f^GF8w@9 zp0ZN_iq{m!eDMw>gq4-at8B@_w3tfFd8iR=3JN9A@Ie^;{zt5UaJpzh<{_-HJ~qC~KJcW$)UhI4gUSL_2LjRk zBD^7g-4ObEkb8*8dh;g>`DJMd)bAeTwD$j+bDdZ8dxGO?3KgN0LwG8*ggGW!RNXKa z595$P4lb)@hWWe#A}Gox@_dqWCG|*?=YJe;z}WXpFHY{S(mT9`B|-!^sfT4t<8?=c!zz(pvO+Y{X4XqHH4b#w)h&^=v;W6^rh+_& zZ7K(KHn0Q|IhtmoTa>jK?gMkDw2^LHE?D+| zoFHKLHZd~FurdSvPHzhJuK2}4M8KfsbRun^Q{SG^RAup4FJ;+`oP@u18s->QFe(n@kuIKt3 zq>a~EjfZ!vR9Aj!I;x$37FA7bL$S5Eq?U9(#9GUDrPot+=r1OvP~_&HHvO6{1O>3O z@Rh$*zX%;vd_})~{#660rC$e{07{4!&vnh#XPbj()T+}i7J=M(A)?cT;45!P&2;}7 z1lN)<+_u}(=Rq(bycHBGZT#|IV7iJ`0N&J0NZIW+IK9YtXJ%8hxR?gd9iNgyhPCOjr) zIScxwCoTbiM{Ov!!?S&*AiRoh^PCxWmNBPLl!Rf*8TUILGvx=f_P~-RtB4Y@@<1(R zxq(LcuKgvtJ%CbhVVYPa$SfpqYUrfITiYiM3@Y*Y*sVj17Vu+BTR^Y9{@-V0pCi~; z(uNO;EF~i$WRaf##lCG!q0f`wd&67(J3GwbmwY1&;(}5cO3uZ&Vd;`eD{S5Fdw>^{ zIhe2rUW%o)W^1&0{6%9)23)J8VsiVpZqUVGs6;4jX*U0WcO7t*qL(FX=pM?`5xjd| zf$)6gLQ+WwdgNhPS`^DDgszWNLI9RxDWZ1o7ZPM0+Icp;_gWYSDAin=`UGj(8v}j4 z6xC)KKl8diGtD#PXe`>YAw^s&M|?I6_lzSz8uHgHP)g!WP}O_2OHp=w?=xi63W2bq z$BUW`*XhH;t_0DKuM$(D-d$C#@K?a{z}JRC9hEinGrN=O=ryR3>)NVAwc2Bu2F8{o z)7;%JS=sjg-ai=%Bp?~YUNMVa2R3c$GtlY*pH~K=hPLW~+WLf{v1_!j(a4zvYu^m( zSJrK5updNYt{shnJkJq>(3e5i6zjgL=# zma3PW=#>|4O#OBdR}eWL*dB3P#O>KUAULxTQ@o;{dRrQ+{(e@Bi>jjR`feM*up3G& za0|kfX++KmM(D%eRcK@T1DzzD+BM7VZkOfcFqT-=!2oIxypg^k2r5f^1Qcm9RJ=7E zeHTl&adogqt21VS8?U!_m63GiFJA|`;ImZJbfNK*UyCRjEp>jiUyt0dU%ve*@_V56 zmudZbBDncd{sHP9qpV0i&?bw1St_r!rayKp0azoa+}B<|2Cqc%m^i#ULOz6}^i<x}oF;o%wD5ig<&d+U0wuD^c!<4fzK?6Hhu0OtJo5rHTdP`2+Wt<6-05k$)*`*m-Ag+Roqi5$p=CKHpv^!7=Y>q@kE+z^9Lx#Ftr+FFZG;JrO74 zXXzN}4$1HW1+Oe>Hw7+RIj3YtLUZuUu|v2kdl{Gb+4Rk;wPH9~KMNaPRVb;Oq~`D7 z&UWtqO-tz+s9nyh;IV)71Cg%oT8&14(30QG%aq6h5B0a$ z|E|mtA>$qG$y#Gpj|S>nbro6x_??@K{_Aul=ic~F!WXIBLc|TQo5C|d6x!-b9hLCu z&d@XZ59a(4+)DB4&s`*QWA7@yG-lGq;V#B*D)>!26zTtm!q?YEC;sV_fM-d2%1J`> z`f2KwznHh6(87-0peQiLQk-|d1`*SOpPx@c-Z9aal1kS34Ul?8?-tUGBx^2!Nf5Xc zed`!yLxGPly(yWkhy+&3B&9zT4k!gs$%4KYP> z-&xT>5AnCGZgw9DQ<~-o%q`w;NuZ9q!_Tn_Zss;~qSv3>#9rOJe&mr~oT^cJ`v923 z1JPV0m*>2w>}meDLXno@mf{sAM1#>`S!yi5zj-Ws2o$K02Xnd_zXPwtlkr?P z$=a3F$Y2Y0?GxChUXdEU|Fy5On9iU9Zo|KRRIgVdLqfi|W;sc`<$2?)<$gee&7cDm zGO29y$qM#j?(J~@hJAVQJ1Ql0(mO(200U51EZvBQh^w?)m%A2Sdin5aNQuaGJcvKHsKqqTzrKEO2NaP^&sJsizqE>~IKAh50= zQ7c5pOjB+dx|gf+yXrSd@=$klHvLw}m+<9Inr_cqmSQ4>WguACK@XK$azs@9@fLvf z+I*~tj`&C&1lV5^*j9N|gQtc6!xKSocAhW++pT9Nj_dIq+9Vy$UkXar%*z*v{EUWw zTa;2Rxjq!qF`(#0YN}n%ag!2zDNm#rSrn`TxEg*{r3<#W>CMkW?G3qQ0-MJpXCbiCdcP^Y8z7=J6KdSuVWfUGrSKt&1B#6cJqf(A_#bBl=An_2tG@?XuQJaY$WNVvB}!&oP?T;T6C>jxlSZ9BS| z9o=d)%uO%+-lnxwlR`tTsRaN*W=A($EN_EBiy{O2J`OP64aoWhY0n;ED;+QB!MOg0 zVsj;WwOtMtNnM(eb25{Xk@u1M*!}uBkY8OWK8ISr{9q<3dngoqDJ>}+pv=C_43`y8{DjIipkyr*8v- zc4m!NSJ8gYp<9ovTR6==Zg<7SICGx8ZSrqOHhX{-gfzIgk-APT9(a6R2-lD#2GG<2tNPtVFh>hV|IJ?R4f#E+2ePT zE&W;sQ)PBAe$@Bob|bDovQmb8UEc2w`nxbD%1fy z4ZWNFnej`{AHCCtcDt{}IclGfJduP#UZn^=y1RoEGm`+M4_Lm>dCkPwYD@z5`|f!R zzFbtp_@(UBPs0nDyxvHeqLNM8i+s`e{hGrPx8EnF9IOWO_Agj^=GcKoQzoC+oa8E7 za(iQbkpUOCb1SCZ)E-Honbp{&Fz*2xxLSa_z0}j2Avs{Hw(c^}dvv-KqLdfV28+ni zU1yVf4KYFtHYac)Y-x$wTIQGi1`MqEZv2z9Io!6xjnon!j^Z$MG~#bDRj(Adgy-*c z%$dFGlTtW|U7EGnZ4Fug6OZF&ka}W1k~Lau(h$sZQ`E^;PLFIv7OZ++Ha`*lXH zWRXEfV0NQ+n3$sJEB#MOpU0E1*@xVaK^TyH;>`AlxOdzSPrOa#9C41$AXBA=?h#2w_Tv22xRDUqH&Ic&J^l z;n5^I?|d~$&{8$~r(PU=7kY#;i_gLs%`Rdm9jt%|WcVgdG@R_zJeh<&xUTQQ)*(e1 zDERW+#ODx9@3R@GxjPo~t~{L_+dnyQmdK0koW9r`YSqh&!Z*|`?56fOXsz}i-wE;^ zbb~Q(=8!GgYD^TdSp47>r?gd}!l zughU}Lk>X|#F#;`l_x`Y?}%vqo5Q+Y$Yp^++LR5SP7h1bFF00Gs}b4i3Z3-HP97Kg;Dp^gn2M+MimJ6MB(Kk8&Hjg@vYcj_%>S z(pjOhQzTG>r63_FvBXI(H+yGGRx~L~T%oj#=CVP(rAds$CIGEZy)L#~*mqYK)I1x~ zva%MNZE885iS|WquU$nx)2;v{<8m`2n zQEF>>+FrrYJ*T<7two3;g+Q0phZmiiN(+k=zI|+WS!wGylLN&)@(kOwJRm8$>y=W9 zX|T$kNczWITQ0D)9x<=;kFtbh-0Zea*bGJ+YQ0smX`jB{z`cqO3IiQu>2$B;R3}TP zbClL(8~7WqSQtEb0z5-{eBU|2AJlN%UDywLk^9D7Eg~ug`rZpD%Hm%D-o5 zYXVrv0{5YgXr(X`Qw&Vypk}->CR818qiR~Wfs+US#10a}49W%gNJoG{-j#R!xwncT zspnP5PNcx$$2|cCQHeJnYFUtDG*ucNErdxJOoA_Sfr+{M+R9{%My1by(997V#Vv*H z(gWT^Xb!U;*v-|FCmYS~e=RWuY^!iUit`;KVpDohJW<@HZ1?nqCsw;3b?1*p*Mid%f8O{}+!t za@Cqu;Fp(TC>6CpXBj~IfmaB9gL3?!px<-!h<^6z}SC8-n&)9`isd5KCa6PnrGbE{f!~ItqqSqlWp!T~0T|gDb}b zBjOi)A`ooZ>EXg|(E_n)J?)uPr+^Z0c~kk<4dFHZ7D7G#luC)E08O!Ile6y~LY!Rj z>*e-yd7gwLsOIn%uI*``tUnLJx~Ev|Q?u$=qb3QlPClNK--KBbbg2Z2m z=|I~s^2m{c4EmkI(1O1%glfSWtYIu>XMF_KY`nO8GzfS-)f2Xh8Tz?xe;r_$1Y zIW~5o+!sMn-7jeUre@;ByndY5(4^w$JjptqB zpfg6HBFFHRpr(l*?fI`nQF&W(CJIifH|AxO%CPm_xML^yp*@a{r+Jn> z$)zcn#F{sEosO6w)L$Is%sW7I{Y*VGuefMUeToX-1yPy>*Pl-Kvx0HkL+Dv zcKPKPJxZsMYF&Cs`5s|FBSA|GUXwJdzsKeU)FIK`@95y@#RHa`d1+Sz?^kY&fy_oeL@VW~7C{+02= zOh4CNdDW(pd3D%X6|+o_s#s~bR0!BjBS&S4CTK|b!0(0QtV(NSqRHJ^DdxF;^C!0T zB|DxgV$Mx~Mf7qwV>5Qrg0j~;%0Yq+rm8?4oqP#)9~xIA?%Vf4E(OjUiWCd1_Rf)~ z)bfYPn?vxs`~~|h`Wsx9zVN6QtOgR~`9=!%F~cu>*vCy4@$%zPR1` zGQk$Q8O%FfyiEJP;61jPSo(c2eCit8qQ$nA zs^Jzo!7OKF2+dKgayG$~gTG`(n2Mo}k?#@R>XPuRLqzjH-q%7XQ_h9(ZvWief!pn@1T5!F^U&d2-1s%@WQtM z94Nn`nwwX)4(Y<$u2wcSK1PfOfy4t}6s3S5r=Qo(IP%1*I-Z~3+ILg<4|u(naKF`B zAY$>zzoLBX^r5`O;}MH14VPWEVAG>1fcF3k8M;6K5_?aKm|TVH6aS?XV&PX&Cb^p} zWGmNC~*SLgMvPrMn zsjSu7R??UgG^yZx(SdUs)&c+%nn?axC*BODsz4=q-_i1AI&u0`!Z8RU4d3AO{;M`k z3<0$2e8>0RqwUY;8|AnhmSW>~G@=>A3?&vePW}cs|3|^McKqp*K{rT!Is8h-mzxt9 zV2BiUv4_6;(fkvD%A8>X5_$j>(JbNRQ>UYa?W=ANPtTZuzS{I+eZwr2epdxx-D^VTWcQI&&X}^LqG2C=FtqHB$x6+jkdCod|KZtD9 z2#sFpB%bG~QvkIuz;Vun{=zADLml!abHqb#Q0)-x31%2uM^3`Gkf@c`Apgo>Of4H| zTVMpux#l7%Pmv|i2=ms+FQ(gkEoVwo7mq1^+{;-HsA>OxvmR@ii-Pp-Yg^yXvW4oL zVuQWH(Bd@)IR)@vWJ+(C{Zyn=zR{3E0nuGzXQ^1Y+QK>VX=aVlU;O6m=pq(2Xp5m& z5l7R0)D-eNKq@caZs7uF-U|X7#y8NyLa`3Vwq3$E6gr8MkR5jvIY(oeGf83u2m;P> z0P5^-X)7UdOhOni?h&tQiQ+yL@#F7+r^#3+HRQkvV^+o|EBbNPzWr9dLZ&6R0?wY| zR!loOu@%4oL8020vPQdZ!?W+|t{0ZK#w9CB!T|Omg6&SN-w68MD|uYB<^q~?*(-<7 zsa2vVqJiVZ5k8S-wxE|o14{OAk3)Lp{UHx^*bZ8o5KAQd|A;X4l%ccDgG#UR;d5$s zP(s86^?_FcPGvjD)(pcV5Fcf|R1tFDtAFbdoie%ba*XQ0LSGR$$xpntRd_^WT9UMn z-&cP(s^?-z28OZ$Vaq7Mww|Z1jgkJfw*G)ABHTQWy2(DoO%)oaR-@Y{!hebd55DQW z@Ok{H)m6MxHLsNx00l9c&&m&^gYkUe!WNC}{;BW_cM$=PN#<&K9;aixarof>Y+OPiO_xXPGs&H8dTj6I zhORpwZh_`fSJ&0vYs1o_K|QmhC<@?N>~PfBztx}DnZ3yYJ)$~~*7MRmb2hK(Tof%@ zKL9kN*w;AwwD=Y|@};V8(AT2}*lkTdqoWHim;esnOat`=3ETiM{cvU)G>>sdo+_`GCrz&1K-!nLpK@_W7khr^8jLBQmaLkewleycn}bU5jzbSnLMH|cZDJ_ z4`w?AZV?@O7O(DVwbV?9*-FQ{WU0Y>k)LX4p4=%f+y+IEQn-%(w-|vJH~>#GJN<-P zX9Z3ehNrB`NeO21UU^*e83*dDOk|D=#%s`~o6^{xOll~kz=M^_4}{k|8GWgVV1mWB zI8eyO|IlFRMm|Q9pOkd_?Ve+)Y<70AbfeAIwiJItvOzJ&6;v__ttVj872Ud>w;AH0+qMtm%;PE?Yq zH5!Sw#|fN;d*wE#F*X=l#Do#EV-ni0hAuBVjPA;_CFfBH-v49eEk+X~lmDwvC4Qaa z3uFH78s0ABqhdI4ZN*`(BROtpi~cv=4WzeYYwxTH>oUrs2JXSQ9gs%F7!lV*#<|&R zuWnt08|t0PrdC~_i_&@;CmAaKi`uDQ(R)vGl>OM)A7|5o`ucJiKCsFJinU{~4g0n> z%%7An7dww_r3e59{DWA~xVe<5|LJah$R?NOFBJ(RU+r77RUHHxmQ7~DXJ*xn$7Ub? z-v+wus~0-R9Ec*-i`#_rCxHQ5IyX^QG@MCEuqbdpE|`Hr)dfEd9Q+g|L)uaAk5$y| z>RC6&Mi|U)u~NzT)#TiBK!lMB6)C57OF_7eoq&|W36(g@>GWPp9CZvp7_aWVE2;w2 zZZ4@FQyS5uE9M$AxxnaBKbI#*8n}*(1N02Do9h_k8mVlw#&exdXdZ`1?59W>0_G~M zrXAj@!Owh6-dASA2)MVj?pWZEfs?VKCZeCYE}BVCv`9=PqM3{jpccthhpt}OXN->; zkfliPe?V<599HVg>op@wR_+9NeXz-0B|s3?9T{3qT7Q`op7bShdq|tD%7I@aTv=TB zJOiM@zH$k!Y)11j@$SCbWrv8=^k8Du(4dQHb7P4@@&GZg#|H9Uqd`p|GCZ8KIi4sw zdLgp<90AOoF*C=M-b<=Nb}*)9@dUB)bUkq|Q*&L9UG07n{!VEcgIsr-U^fS+GVA={ zm-J-U6`Lj%->yRCI*=0ckUJ4%IzBqJw9~crwj#xOXSIliB?_LytW=?-sqyOQCt+k- zDbmoT{2{d~i1cM`Vw=XP^+j(88-5pc!LE`Y)%BO!ND#ue->d70y08^B{6YfF)A0Q5 zgiYk23IUJX;y3;{mZ9l^+s}jdCP+BTUx^malXbRR9Oj0PyMt-A#j3%0eIa4KW%&@^q*OoyxS9QGF0MYhfJeNlzcnras^02bL_3^ zbK~O8nH@OTRatZsnO2&-J&O9N?X8@XnI~a_fa3==I|_NZG=<()XFwP+FEuyG4Dqj6c6TNhIAEl=lmvnY=XaLo*?@WMmS4cPz-_TJ2DxQm#TBZWen|c(;P8t~7H1 ze9ZodrPwRLgB7t%3}k9AM}ze6HTSItifSS*C6;K^x&Rf(&fi5pKr6L;?w>Q;pc`B+ z!V3J#lEKk=<{Wk~nrVx9rzk1IwanujFSyWp*`C}QOXCX&J1+70ue>ch6eJT8W{T@* zDxN`Q+C;Y|4`W@34e3$>Fy@r}+9e=$`okt% zG}3~RNdH{Nl@en$GFOwI-KQ0Za!N)}A$xG$HUx*4AimP*hLNibN86x`1W)@9@h@ha z7RCA(S!-_`DlApvt8mncRy{m?RxB08JIAHmK`3Gqxah~Dd?`e7(i6>?4KsQNkp~uM z#3Qfg^QZir@>pf1s^UUf{Z8Z09ht!azr_Uz2LQV4Wf!&%sg%^d@tTn89=x$aSN{|E zz2jUo)Ik3q+;DB4#5G>u1j#Sbl04lber%d5^8EBHtG0Ujm>!#aZDEEDx-X2C0Iv=GxdOpP?1e-ODHb|HKD@AQCaGeQ4q zb$qC@?CSG8t&b72Y}(_m(3*O_;+Md`9{ssfJp*T;eNfY+^%P&=mv`2zT1@#06F{^H zcc<$V>domzmVFBTQh#ZqQrDms=VT(lQghfMIv?J4*sD+$u_xsdrBWs=Y?IF~7^7oq%@l5D2Vlci+TyI&3bOgOyUN@CB+lJYPOUipxP~|7 zd~8S4r%fOis;8V)P(PhxmKP)RXVy%VPFF@PNQpUHWiSMxC^u(XTbQ}d=jCM+aXTa! zF7*4hPS-B&GJOODLW#>o|2Lf8XgaeYb57Mb++^qT4!iyk$X?O}CdPZoU*S`^64Wn0 zqu%9nVh@c=ClS*Pz4n))yAh>^tOOqBhyDtK7LRQ%C`KWIk!qCW~dw5zSW` z3n_Z!A!(9lPl@MB+-iTsqb4UPXbehE5L+M_z%-^kwDn8kj8FoS0HLE~cj|5?x+C52 zC}tis1sq`VF?X^KFsXSu3LC~LFze1^9TCxe=I(4*i%q`~bwXm$I&9`V%4W3q{}GVL zZnl0UM5hdD#C}HFCAuyVjMBsC36-T2r|XI7+Sg)#Yve2-e`PJ=YzCp=SAz7U_OWpa z%=gOGIFrvux-f>j>rxU`3(yzj+QC8t*o%9;!k3iOJP$ga1bc^=K*VF-gPqX2zbu(jK`6iDl9}w|vdpIW5U~xw=Rj8Oks}Y&t zsJrYEYe*TbR?fs2>kYO43qZSIWi*%xbS$x8MqO3K&Npdl_zBdG@ zc`2+4xBM8pc{m$qc1O!8pwSuH68mJF+u@*TGACC@kDkgTLLV8rK6aqP$1IHhbX?pQ zziDoqp;e%;GOYS0{(ywo^q7{%{d8}KE%-x1#~QReeARdxK&2hl&N|t#tgjm3+a#aH z!I02}z{x;dPVnXqT;X$WxZRu0-(8_mK~j}*?`M;GIBn5Hf5UZJMsb&2Hx)J4V&T() z!P`ddLc2?mdf6va`dnrAkQNaZt zw0zPA75IeZvdoxAg`S8%p7A^Fp}N>#N8$TF?cY^aIYPiJu*IYL zp*B1xD+^ES*^9~u=u)yd;RDJxGnDGO31tQ~Wr zKsHNF>+CN`7Y3f3nf4NLk|2f<*{kPH{(>_>3kAvx}dizD_%=@UNOkS z3_Ep`6xn+hh4OksV2c)Gw-bf$@g`9G-)h>qAiWLs^KmIf+LRtd#((8YrS)sW809~y z*BwO1Xf|y207unc_*a-g(8gKAfM{gI00$qf%G5NRW?BEnB2grE?k2JTEVKX>^Vl9X zk`p)3hyeJzVW0Ri9v6FLM6@J^0v{WcivR!s009_~H6j}Q_S&;ZMd^u}>^E z&hC<^Cu5IN4_Wb64aA(=FiQ>uC_~jr^hsdU<%GEhD^<0e2ZcYpPAuarbKQ)Lk)oVt z<~e+OVFs^+%fEsl5l#wRHm$NuR$$?(PcQkWdN#+h)MLFrK+8FDBm`^h*_&Ix)0*NIFtM_TEd0bUGN)sOkVjj~_d4E-iM;HJH zD{XVsGQf{xJSIUCSeNtTqy8ae6t1#(bEd3$a?p&XHq>FA->S;UI=LF54O{(GI!RlM k?x>aO@fJ;WhyZ_wsnv8wmmyLZy8s2jCjpgY492to0LZ&YtN;K2 literal 0 HcmV?d00001 diff --git a/public/pokemon-logo.png b/public/pokemon-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ed90ba2207fd626ca74fa4ea7977d71e44394315 GIT binary patch literal 119125 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

+

+ Select you favorite pokemon types (max 4) +

+
+ {isLoading && ( +
+ + + + + + + + + + + + +
+ )} +
+ {data && + data.length && + data.map((pokemonType) => { + const isSelected = + // πŸ§‘πŸ»β€πŸ’» 1.d: replace the empty array with the selectedPokemonTypes state variable. + // πŸ’£ We can remove these ignores when we apply the code + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + [].includes(pokemonType); + const hasSelectedAllOptions = [].length === 4; + + return ( + + ); + })} +
+ + +
+
+ ); +}; diff --git a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/components/PokemonOptions.tsx b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/components/PokemonOptions.tsx new file mode 100644 index 0000000..e2c27c5 --- /dev/null +++ b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/components/PokemonOptions.tsx @@ -0,0 +1,129 @@ +import { Skeleton } from '@shared/components/Skeleton/Skeleton.component'; +import { + TPokemonCardsApiResponse, + usePokedex +} from '@shared/hooks/usePokedex'; +import classNames from 'classnames'; +import { FormEvent } from 'react'; + +interface IPokemonOptions { + type: string; + // πŸ§‘πŸ»β€πŸ’» 2.h: Add two new props called onPokemonSelection which takes a string[] and string as params and another + // variable called defaultSelectedPokemon which is an optional string[]. +} + +export const PokemonOptions = ({ type }: IPokemonOptions) => { + // πŸ§‘πŸ»β€πŸ’» 2.d: Create a selectedPokemon useState variable. Default value to be [] + + // πŸ§‘πŸ»β€πŸ’» 2.i: Replace the default of selectedPokemon from [] to the defaultSelectedPokemon. This will remember which cards were selected when the component re-renders. + + // ✍🏻 This is already done for you. Feel free to have a look how it works in shared/hooks/usePokedex + const { data, isLoading, isError } = usePokedex< + TPokemonCardsApiResponse[] + >({ + path: 'cards', + queryParams: `pageSize=4&q=types:${type}&supertype:pokemon`, + skip: type === undefined + }); + + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); + + // πŸ§‘πŸ»β€πŸ’» 2.j: call onPokemonSelection(selectedPokemon, type); + }; + + const togglePokemonSelection = (pokemonId: string) => { + // πŸ’£ We can get rid of this line once we start using the type param. + console.log(pokemonId); + // πŸ§‘πŸ»β€πŸ’» 2.g: We need to now update the state for when a pokemon card is selected or not. + // IF selectedPokemon includes the pokemonId then we need to de-select that pokemon card. + // ELSE we add the pokemon id to the array of pokemon cards [...selectedPokemon, pokemonId] and then setSelectedPokemon(newValues) (make this a variable as we will need it for later.) + // You should now start to see the pokemon being selected and de-selected. But the next thing we need to do is update the state within the screen. Search for 2.h + // πŸ§‘πŸ»β€πŸ’» 2.k: Inside the ELSE, check if the newlySelectedPokemon has the length of 2. IF it does, call onPokemonSelection(newlySelectedPokemon, type);. Head over to the Screen.tsx component to finish it off. + }; + + return ( +
+

+ {type} Pokemon +

+
+
+ {isLoading && ( +
+ + + + +
+ )} +
+ {data && + data.length > 0 && + data.map((pokemonCard) => { + // πŸ§‘πŸ»β€πŸ’» 2.e: Replace the empty arrays with the selectedPokemon variable we created. + const isSelected = [].find( + (pokemonId) => pokemonId === pokemonCard.id + ); + const allPokemonSelected = [].length === 2; + + return ( + + ); + })} +
+ + +
+
+
+ ); +}; diff --git a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/components/Screen.tsx b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/components/Screen.tsx new file mode 100644 index 0000000..62d6c72 --- /dev/null +++ b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/components/Screen.tsx @@ -0,0 +1,84 @@ +/** + * Exercise: 🧼 State Colocation vs πŸͺœ State Lifting + * + * πŸ€” Observations of this file + * So the lead developer wanted us to manage the state for the selected pokemon types & the selected pokemon at this level so those variables can be used here and within the children. Each variable will be an array of strings which represent the type or the id of the selected pokemon. + * + * We need to tackle this in stages... + * + * Stage one (follow 1.* steps) - Creating the form that returns the pokemon types and saving those selected types to the lifted state variable + * Stage two (following 2.* steps) - Using those types, we will render the pokemon options component + * + */ + +export const Screen = () => { + // πŸ§‘πŸ»β€πŸ’» 1.a: Create a useState variable called selectedPokemonTypes, setSelectedPokemonTypes. Default to be an empty array. + + // πŸ§‘πŸ»β€πŸ’» 2.a: Create a useState> variable called selectedPokemon, setSelectedPokemon. Default to be an object {}. + + // πŸ§‘πŸ»β€πŸ’» 1.h: Create a function called onPokemonTypesUpdate which will take a types: string[] param. Pass that into the Form component as a prop. The function will just need setSelectedPokemonTypes for now. + // πŸŽ‰ STAGE ONE COMPLETED you should now be able to see the types display, select them and then the state in the screen gets updated. + + // πŸ§‘πŸ»β€πŸ’» 2.m: You will now start to see the happy path all working fine, however when you change to different pokemon types and receive a new set of pokemon you now get some messy state where selectedPokemon is more than 8. To fix this, write the following code inside 1.h function (before the setSelectedPokemonTypes) + /* + const newlyUpdatedPokemon = { ...selectedPokemon }; + + selectedPokemonTypes + .filter((type) => { + return !types.find((selectedType) => selectedType === type); + }) + .forEach((type) => { + delete newlyUpdatedPokemon[type]; + }); + + setSelectedPokemon(newlyUpdatedPokemon); + */ + // STAGE TWO completed. You have now built the screen. BUT 🐞 there is a bug where the PokemonOptions re-renders the types that did not need to update when you change your types after one try. The reason is the "key" prop using index. The api has no identifier per type. If you enjoyed this exercise have a look into fixing it and make a pr. + + // πŸ§‘πŸ»β€πŸ’» 2.l: Create a function called onPokemonSelection which will take a pokemon: string[], type: string + // Then create a newlySelectedPokemon variable which will be a copy of the current selectedPokemon {...selectedPokemon} + // assign the newlySelectedPokemon[type] to equal the pokemon variable. + // setSelectedPokemon(newlySelectedPokemon); + + return ( +
+ hello +
+
+
+

+ Pokemon Battle Picker + + Battle Picker + +

+
+
+ {/* πŸ§‘πŸ»β€πŸ’» 1.b: Render pokemon types form from ./components/Form and then head over to the form component */} +
+
+ {/* πŸ§‘πŸ»β€πŸ’» 2.b: Loop through the selectedPokemonTypes and pass down the type property to the PokemonOptions (./components/PokemonOptions) component. You will also need a key to be on the component. I used `${pokemonType}-${index}` */} +
+ + {/* πŸ§‘πŸ»β€πŸ’» 2.c: We need to check if the KEYS in the selectedPokemon object equal 4 and the selectedPokemonTypes length is 4 before rendering the code snippet below. Head over to PokemonOptions when completed. */} + {/* + + */} +
+
+ ); +}; diff --git a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/exercise.stories.tsx b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/exercise.stories.tsx new file mode 100644 index 0000000..b808a12 --- /dev/null +++ b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/exercise.stories.tsx @@ -0,0 +1,24 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Exercise } from './exercise'; + +const meta: Meta = { + title: + 'Lessons/πŸ₯‰ Bronze/🧼 State Colocation vs πŸͺœ State Lifting/02-Exercise', + component: Exercise, + parameters: { + layout: 'fullscreen' + } +}; + +export default meta; +type Story = StoryObj; + +/* + * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas + * to learn more about using the canvasElement to query the DOM + */ +export const Default: Story = { + play: async () => {}, + args: {} +}; diff --git a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/exercise.tsx b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/exercise.tsx new file mode 100644 index 0000000..ee28457 --- /dev/null +++ b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/exercise/exercise.tsx @@ -0,0 +1,4 @@ +import { Screen } from './components/Screen'; + +// Head over to screen to get started. +export const Exercise = () => ; diff --git a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Form.tsx b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Form.tsx new file mode 100644 index 0000000..e52e78f --- /dev/null +++ b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Form.tsx @@ -0,0 +1,115 @@ +import { Skeleton } from '@shared/components/Skeleton/Skeleton.component'; +import { + TPokemonTypesApiResponse, + usePokedex +} from '@shared/hooks/usePokedex'; +import classNames from 'classnames'; +import { FormEvent, useState } from 'react'; + +interface IForm { + onPokemonTypesUpdate: (types: string[]) => void; +} + +export const Form = ({ onPokemonTypesUpdate }: IForm) => { + const [selectedPokemonTypes, setSelectedPokemonTypes] = useState< + string[] + >([]); + + const { data, isLoading } = usePokedex({ + path: 'types', + queryParams: 'pageSize=8' + }); + + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); + + if (selectedPokemonTypes.length === 4) { + onPokemonTypesUpdate(selectedPokemonTypes); + } + }; + + const onPokemonTypeSelection = (type: string) => { + if (selectedPokemonTypes.includes(type)) { + setSelectedPokemonTypes( + selectedPokemonTypes.filter( + (pokemonType) => pokemonType !== type + ) + ); + } else { + setSelectedPokemonTypes([...selectedPokemonTypes, type]); + } + }; + + return ( +
+

+ Select you favorite pokemon types (max 4) +

+
+ {isLoading && ( +
+ + + + + + + + + + + + +
+ )} +
+ {data && + data.length && + data.map((pokemonType) => { + const isSelected = + selectedPokemonTypes.includes(pokemonType); + const hasSelectedAllOptions = + selectedPokemonTypes.length === 4; + + return ( + + ); + })} +
+ + +
+
+ ); +}; diff --git a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/PokemonOptions.tsx b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/PokemonOptions.tsx new file mode 100644 index 0000000..cb2c8e5 --- /dev/null +++ b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/PokemonOptions.tsx @@ -0,0 +1,141 @@ +import { Skeleton } from '@shared/components/Skeleton/Skeleton.component'; +import { + TPokemonCardsApiResponse, + usePokedex +} from '@shared/hooks/usePokedex'; +import classNames from 'classnames'; +import { FormEvent, useState } from 'react'; + +interface IPokemonOptions { + type: string; + onPokemonSelection: (pokemonIds: string[], type: string) => void; + defaultSelectedPokemon?: string[]; +} + +export const PokemonOptions = ({ + type, + onPokemonSelection, + defaultSelectedPokemon = [] +}: IPokemonOptions) => { + // 🧼 State Colocation: we only want to have 2 cards in each component selected and use that for validation. + const [selectedPokemon, setSelectedPokemon] = useState( + // πŸͺœ State Lifting: We inherit the lifted state to maintain the selected options when we change pokemon types. + defaultSelectedPokemon + ); + + // 🧼 State Colocation: We want to only call this api for the type provided and not all the types selected. + const { data, isLoading, isError } = usePokedex< + TPokemonCardsApiResponse[] + >({ + path: 'cards', + queryParams: `pageSize=4&q=types:${type}&supertype:pokemon`, + skip: type === undefined + }); + + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); + + // πŸͺœ State Lifting passing a function in as a prop to update the state above. + onPokemonSelection(selectedPokemon, type); + }; + + const togglePokemonSelection = (pokemonId: string) => { + if (selectedPokemon.includes(pokemonId)) { + setSelectedPokemon( + selectedPokemon.filter( + (selectedPokemonId) => selectedPokemonId !== pokemonId + ) + ); + } else { + const newlySelectedPokemon = [...selectedPokemon, pokemonId]; + // 🧼 State Colocation: Updating the visual state of the selected pokemon. + setSelectedPokemon(newlySelectedPokemon); + + if (newlySelectedPokemon.length === 2) { + // πŸͺœ State Lifting passing a function in as a prop to update the state above. + onPokemonSelection(newlySelectedPokemon, type); + } + } + }; + + return ( +
+

+ {type} Pokemon +

+
+
+ {isLoading && ( +
+ + + + +
+ )} +
+ {data && + data.length > 0 && + data.map((pokemonCard) => { + const isSelected = selectedPokemon.find( + (pokemonId) => pokemonId === pokemonCard.id + ); + const allPokemonSelected = + selectedPokemon.length === 2; + + return ( + + ); + })} +
+ + +
+
+
+ ); +}; diff --git a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Screen.tsx b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Screen.tsx new file mode 100644 index 0000000..045650a --- /dev/null +++ b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Screen.tsx @@ -0,0 +1,88 @@ +import { useState } from 'react'; +import { Form } from './Form'; +import { PokemonOptions } from './PokemonOptions'; + +export const Screen = () => { + // πŸͺœ State Lifting: Setting up shared state variables so the components in this scope can read and use them + const [selectedPokemonTypes, setSelectedPokemonTypes] = useState< + string[] + >([]); + + // πŸͺœ State Lifting: Setting up shared state variables so the components in this scope can read and use them + const [selectedPokemon, setSelectedPokemon] = useState< + Record + >({}); + + // πŸͺœ State Lifting: Setting up a function which will update the state instead of bleeding this complexity into the UI component. + const onPokemonTypesUpdate = (types: string[]) => { + const newlyUpdatedPokemon = { ...selectedPokemon }; + + selectedPokemonTypes + .filter((type) => { + return !types.find((selectedType) => selectedType === type); + }) + .forEach((type) => { + delete newlyUpdatedPokemon[type]; + }); + + setSelectedPokemon(newlyUpdatedPokemon); + + setSelectedPokemonTypes(types); + }; + + // πŸͺœ State Lifting: Setting up a function which will update the state instead of bleeding this complexity into the UI component. + const onPokemonSelection = (pokemon: string[], type: string) => { + const newPokemon = { ...selectedPokemon }; + newPokemon[type] = pokemon; + setSelectedPokemon(newPokemon); + }; + + return ( +
+ hello +
+
+
+

+ Pokemon Battle Picker + + Battle Picker + +

+
+
+
+
+
+ {selectedPokemonTypes.map((pokemonType, index) => ( + + ))} +
+ + {Object.keys(selectedPokemon).length === 4 && + selectedPokemonTypes.length === 4 && ( + + )} +
+
+ ); +}; diff --git a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/final.stories.tsx b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/final.stories.tsx new file mode 100644 index 0000000..0b0f87b --- /dev/null +++ b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/final.stories.tsx @@ -0,0 +1,24 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Final } from './final'; + +const meta: Meta = { + title: + 'Lessons/πŸ₯‰ Bronze/🧼 State Colocation vs πŸͺœ State Lifting/03-Final', + component: Final, + parameters: { + layout: 'fullscreen' + } +}; + +export default meta; +type Story = StoryObj; + +/* + * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas + * to learn more about using the canvasElement to query the DOM + */ +export const Default: Story = { + play: async () => {}, + args: {} +}; diff --git a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/final.tsx b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/final.tsx new file mode 100644 index 0000000..0bcdfa9 --- /dev/null +++ b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/final.tsx @@ -0,0 +1,3 @@ +import { Screen } from './components/Screen'; + +export const Final = () => ; diff --git a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/lesson.mdx b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/lesson.mdx new file mode 100644 index 0000000..79ff880 --- /dev/null +++ b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/lesson.mdx @@ -0,0 +1,123 @@ +import { Meta } from '@storybook/blocks'; + + + +--- + +# 🧼 State Colocation vs πŸͺœ State Lifting + +Understanding the difference between **state colocation** and **state lifting** is crucial for managing state effectively in React apps. Although they both deal with the _placement_ of state, they serve **opposite purposes**. + +--- + +## 🧼 State Colocation + +### What is it? + +Keep state **as close as possible** to where it’s needed. + +```jsx +function SearchInput() { + const [query, setQuery] = useState(''); // colocated inside the component that needs it + + return ( + setQuery(e.target.value)} /> + ); +} +``` + +### What It Means: + +Only the component that directly uses the state should own it. This minimizes prop drilling and makes the component more self-contained. + +### When to Use + +- Only one component uses the state +- No need to share the state with siblings or parents + +### Benefits + +- Easier to maintain and test +- Reduces unnecessary props +- Keeps state logically scoped + +--- + +## πŸͺœ State Lifting + +### What is it? + +Move state **up** the component tree to share it across multiple components. + +```jsx +function Parent() { + const [count, setCount] = useState(0); // lifted up here + + return ( + <> + setCount(count + 1)} + /> + + + ); +} +``` + +### What It Means + +If two or more components need access to or control over the same piece of state, lift it to their **closest common ancestor**. + +### When to Use + +- Two or more components need to read from or update the same state +- You need synchronized behavior across sibling components + +### Benefits + +- Keeps state in sync +- Prevents duplication or divergence of values +- Encourages better separation of concerns + +--- + +## 🧠 Summary Table + +| Pattern | Goal | Where State Lives | When to Use | +| -------------------- | ------------------------------------------ | ----------------------- | --------------------------------------- | +| **State Colocation** | Keep state near the component that uses it | Inside the component | When only one component needs the state | +| **State Lifting** | Share state across components | Common parent component | When multiple components need the state | + +--- + +## 🧠 Rule of Thumb + +- Use **colocation** by default. +- Use **lifting** when you need to **share or sync state** between components. + +--- + +## Exercise + +### Scenario + +You are creating a part of the new Pokemon Battle game and the screen you are working on is the "Pick your team" screen. We need to be able to choose up to four pokemon types and then choose 2 randomly picked pokemon from each type before we move onto the battle screen. The screen will work like this: + +1. You select four options from the form and select get Pokemon. +2. You will then be presented a grid which will display four different Pokemon per type. +3. You select two pokemon from each type to be your chosen pokemon for the battle +4. You click Ready to battle. + +### What we are going to do? + +The lead developer on the team has structured how the screen should work: + +- **components/Screen** - manages the state selectedPokemonTypes & selectedPokemonForBattle and handles the updating of those variables. +- **components/Form** - fetches all the pokemon types and displays a form where the player can select up to four types and then click get pokemon to update the screens state. +- **components/PokemonOptions** - fetches the pokemon for the type it has been given, handles the selection of only 2 in each group and then updates the screens state. +- **shared/hooks/usePokedex** - There is a reuseable react hook that we can already use in the form/pokemon options to display the data that we want to display. The pokedex has two apis known as "types" and "cards" api. + +## Issues + +Any issues or improvements to the course please raise [here](https://github.com/code-mattclaffey/react-design-patterns/issues/new). diff --git a/src/shared/hooks/usePokedex.ts b/src/shared/hooks/usePokedex.ts new file mode 100644 index 0000000..5b2062a --- /dev/null +++ b/src/shared/hooks/usePokedex.ts @@ -0,0 +1,84 @@ +// define the api types like a generic + +import { useEffect, useReducer } from 'react'; + +export type TPokemonCardsApiResponse = { + id: string; + name: string; + images: { + small: string; + }; +}; + +export type TPokemonTypesApiResponse = string; + +type TTypesApi = { + path: 'types'; + skip?: boolean; + queryParams?: string; +}; + +type TCardsApi = { + path: 'cards'; + queryParams?: string; + skip?: boolean; +}; + +interface IUsePokedexState { + data?: TResponse; + isError?: boolean; + isLoading?: boolean; +} + +const usePokedexReducer = ( + state: IUsePokedexState, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + action: { type: string; payload?: any } +): IUsePokedexState => { + switch (action.type) { + case 'SUCCESS': + return { ...state, isLoading: false, data: action.payload }; + case 'LOADING': + return { ...state, isLoading: true }; + case 'ERROR': + return { ...state, isLoading: false }; + default: + return state; + } +}; + +export const usePokedex = ({ + path, + queryParams = '', + skip = false +}: TCardsApi | TTypesApi): IUsePokedexState => { + const [state, dispatch] = useReducer(usePokedexReducer, { + isError: false, + isLoading: false, + data: undefined + }); + + useEffect(() => { + if (skip) return; + + const getData = async () => { + try { + dispatch({ type: 'LOADING' }); + const response = await fetch( + `https://api.pokemontcg.io/v2/${path}?${queryParams}` + ); + const json = await response.json(); + + dispatch({ type: 'SUCCESS', payload: json.data }); + } catch (e) { + dispatch({ type: 'ERROR' }); + + console.error('Error'); + } + }; + + getData(); + }, [skip, path, queryParams]); + + return state; +}; From 0143ceb5a9e6cd22a26aeb5e15a481cf40363999 Mon Sep 17 00:00:00 2001 From: code-mattclaffey Date: Fri, 23 May 2025 10:15:14 +0100 Subject: [PATCH 5/5] fix: button colours --- .../StateColocationVsStateLifting/final/components/Form.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Form.tsx b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Form.tsx index e52e78f..7b56896 100644 --- a/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Form.tsx +++ b/src/course/02- lessons/01-Bronze/StateColocationVsStateLifting/final/components/Form.tsx @@ -75,15 +75,15 @@ export const Form = ({ onPokemonTypesUpdate }: IForm) => {

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Ꮽ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 { + // πŸ§‘πŸ»β€πŸ’» 1.c: Setup a useState state colocation variable called selectedPokemonTypes, setSelectedPokemonTypes which will have a default of [] + + // ✍🏻 This is already done for you. Feel free to have a look how it works in shared/hooks/usePokedex + const { data, isLoading } = usePokedex({ + path: 'types', + queryParams: 'pageSize=8' + }); + + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); + + // πŸ§‘πŸ»β€πŸ’» 1.g: now we want to validate whether the selectedPokemonTypes have 4 items in the array before we call onPokemonTypesUpdate(selectedPokemonTypes). + + // Once completed, head over to Screen.tsx as the Form component will be complaining about a missing prop. + }; + + const onPokemonTypeSelection = (type: string) => { + // πŸ’£ We can get rid of this line once we start using the type param. + console.log(type); + // πŸ§‘πŸ»β€πŸ’» 1.e: we need to check IF the selectedPokemonTypes already has the selectedType + // because we need to toggle it on and off. If it is selected, we just setSelectedPokemonTypes with the filtered out type + // if it's not in there then we set the type [...selectedPokemonTypes, type]; + }; + + return ( +