From ca0c0f1a6043afb96d6a9489a631c038be945bcd Mon Sep 17 00:00:00 2001 From: Xander Bil Date: Mon, 18 Nov 2024 23:58:58 +0100 Subject: [PATCH 1/3] zess: vingo cleanup + added/updated github actions --- .github/workflows/build.yml | 4 ++ .github/workflows/vingo.yml | 46 +++++++++++++++++++ .github/workflows/vingo_audit.yml | 27 +++++++++++ .github/workflows/vinvoor_format_lint.yml | 6 +++ .../src/m20240903_194156_create_scan.rs | 6 +-- vingo/src/main.rs | 2 +- vingo/src/routes/auth.rs | 12 ++--- vingo/src/routes/info.rs | 4 +- vingo/src/routes/leaderboard.rs | 2 +- vingo/src/routes/scans.rs | 2 +- vingo/src/routes/seasons.rs | 4 +- 11 files changed, 98 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/vingo.yml create mode 100644 .github/workflows/vingo_audit.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f463cd7..b00cdf8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,10 @@ on: - main pull_request: +concurrency: + group: docker-main + cancel-in-progress: true + jobs: build-and-push: runs-on: ubuntu-latest diff --git a/.github/workflows/vingo.yml b/.github/workflows/vingo.yml new file mode 100644 index 0000000..44a337f --- /dev/null +++ b/.github/workflows/vingo.yml @@ -0,0 +1,46 @@ +--- +name: Vingo format and clipy check + +on: + push: + branches: + - main + paths: + - .github/workflows/vingo.yml + - 'vingo/**/*.rs' + pull_request: + paths: + - .github/workflows/vingo.yml + - 'vingo/**/*.rs' + workflow_dispatch: + +jobs: + + formatting: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install latest rust toolchain + uses: actions-rs/toolchain@v1.0.6 + with: + toolchain: stable + components: rustfmt + override: true + + - name: Check formatting + working-directory: vingo/ + run: cargo fmt -- --check + + clipy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install latest rust toolchain + uses: actions-rs/toolchain@v1.0.6 + with: + toolchain: stable + components: clippy + override: true + - name: Clippy check + working-directory: vingo/ + run: cargo clippy --locked --all-targets --all-features diff --git a/.github/workflows/vingo_audit.yml b/.github/workflows/vingo_audit.yml new file mode 100644 index 0000000..fb7b712 --- /dev/null +++ b/.github/workflows/vingo_audit.yml @@ -0,0 +1,27 @@ +--- +name: Vingo Audit Rust dependencies +on: + pull_request: + paths: + - .github/workflows/vingo_audit.yml + - 'vingo/**/Cargo.toml' + - 'vingo/**/Cargo.lock' + + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +jobs: + security_audit: + runs-on: ubuntu-latest + + permissions: + issues: write + checks: write + + steps: + - uses: actions/checkout@v4 + - uses: rustsec/audit-check@v1.4.1 + working-directory: vingo/ + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/vinvoor_format_lint.yml b/.github/workflows/vinvoor_format_lint.yml index 24a6b47..3195e8f 100644 --- a/.github/workflows/vinvoor_format_lint.yml +++ b/.github/workflows/vinvoor_format_lint.yml @@ -4,7 +4,13 @@ on: push: branches: - main + paths: + - .github/workflows/vinvoor_format_lint.yml + - 'vinvoor/**' pull_request: + paths: + - .github/workflows/vinvoor_format_lint.yml + - 'vinvoor/**' jobs: format-and-lint: diff --git a/vingo/migration/src/m20240903_194156_create_scan.rs b/vingo/migration/src/m20240903_194156_create_scan.rs index 4ac9605..fd49f10 100644 --- a/vingo/migration/src/m20240903_194156_create_scan.rs +++ b/vingo/migration/src/m20240903_194156_create_scan.rs @@ -8,7 +8,7 @@ pub struct Migration; enum Scan { Table, Id, - ScanTime, + Time, CardSerial, } @@ -22,9 +22,7 @@ impl MigrationTrait for Migration { .table(Scan::Table) .col(pk_auto(Scan::Id)) .col(text(Scan::CardSerial)) - .col( - timestamp_with_time_zone(Scan::ScanTime).default(Expr::current_timestamp()), - ) + .col(timestamp_with_time_zone(Scan::Time).default(Expr::current_timestamp())) .foreign_key( ForeignKey::create() .from(Scan::Table, Scan::CardSerial) diff --git a/vingo/src/main.rs b/vingo/src/main.rs index 0341d2a..d8cacdb 100644 --- a/vingo/src/main.rs +++ b/vingo/src/main.rs @@ -26,7 +26,7 @@ use tower_sessions::{cookie::SameSite, MemoryStore, SessionManagerLayer}; use migration::{Migrator, MigratorTrait}; -const DB_URL: LazyLock = LazyLock::new(|| { +static DB_URL: LazyLock = LazyLock::new(|| { env::var("POSTGRES_CONNECTION_STRING").expect("POSTGRES_CONNECTION_STRING not present") }); diff --git a/vingo/src/routes/auth.rs b/vingo/src/routes/auth.rs index 21420c3..1cf66c6 100644 --- a/vingo/src/routes/auth.rs +++ b/vingo/src/routes/auth.rs @@ -19,15 +19,15 @@ use crate::AppState; use super::util::errors::{ResponseResult, ResultAndLogError}; use super::util::session::{get_user, SessionKeys}; -const ZAUTH_URL: LazyLock = +static ZAUTH_URL: LazyLock = LazyLock::new(|| env::var("ZAUTH_URL").expect("ZAUTH_URL not present")); -const CALLBACK_URL: LazyLock = +static CALLBACK_URL: LazyLock = LazyLock::new(|| env::var("ZAUTH_CALLBACK_PATH").expect("ZAUTH_CALLBACK_PATH not present")); -const FRONTEND_URL: LazyLock = +static FRONTEND_URL: LazyLock = LazyLock::new(|| env::var("FRONTEND_URL").expect("FRONTEND_URL not present")); -const ZAUTH_CLIENT_ID: LazyLock = +static ZAUTH_CLIENT_ID: LazyLock = LazyLock::new(|| env::var("ZAUTH_CLIENT_ID").expect("ZAUTH_CLIENT_ID not present")); -const ZAUTH_CLIENT_SECRET: LazyLock = +static ZAUTH_CLIENT_SECRET: LazyLock = LazyLock::new(|| env::var("ZAUTH_CLIENT_SECRET").expect("ZAUTH_CLIENT_SECRET not present")); pub async fn current_user(session: Session) -> ResponseResult> { @@ -98,7 +98,7 @@ pub async fn callback( let zauth_url = ZAUTH_URL.to_string(); // get token from zauth with code let token = client - .post(&format!("{zauth_url}/oauth/token")) + .post(format!("{zauth_url}/oauth/token")) .basic_auth( ZAUTH_CLIENT_ID.to_string(), Some(ZAUTH_CLIENT_SECRET.to_string()), diff --git a/vingo/src/routes/info.rs b/vingo/src/routes/info.rs index fcc1bef..57ce2dc 100644 --- a/vingo/src/routes/info.rs +++ b/vingo/src/routes/info.rs @@ -6,7 +6,7 @@ pub struct Version { version: String, } pub async fn version() -> Json { - return Json(Version { + Json(Version { version: env!("CARGO_PKG_VERSION").to_string(), - }); + }) } diff --git a/vingo/src/routes/leaderboard.rs b/vingo/src/routes/leaderboard.rs index 98eea9b..de0fc98 100644 --- a/vingo/src/routes/leaderboard.rs +++ b/vingo/src/routes/leaderboard.rs @@ -39,7 +39,7 @@ pub async fn get( let position_change = leaderboard_last_week .iter() .find(|v| v.id == user.id) - .and_then(|v| Some(v.position - user.position)); + .map(|v| v.position - user.position); user.position_change = position_change; } diff --git a/vingo/src/routes/scans.rs b/vingo/src/routes/scans.rs index ec59943..e211179 100644 --- a/vingo/src/routes/scans.rs +++ b/vingo/src/routes/scans.rs @@ -19,7 +19,7 @@ use super::util::{ session::{get_season, get_user}, }; -const SCAN_KEY: LazyLock = +static SCAN_KEY: LazyLock = LazyLock::new(|| env::var("SCAN_KEY").expect("SCAN_KEY not present")); pub async fn get_for_current_user( diff --git a/vingo/src/routes/seasons.rs b/vingo/src/routes/seasons.rs index 379d985..5aa88fc 100644 --- a/vingo/src/routes/seasons.rs +++ b/vingo/src/routes/seasons.rs @@ -36,7 +36,7 @@ pub async fn get_all(state: State) -> ResponseResult ResponseResult> { - Ok(Season::find() + Season::find() .column_as( Expr::col(season::Column::Start) .lte(Expr::current_date()) @@ -50,7 +50,7 @@ pub async fn db_seasons(db: &DatabaseConnection, future: bool) -> ResponseResult .into_model::() .all(db) .await - .or_log((StatusCode::INTERNAL_SERVER_ERROR, "failed to get seasons"))?) + .or_log((StatusCode::INTERNAL_SERVER_ERROR, "failed to get seasons")) } #[derive(Debug, Serialize, Deserialize)] From e1494ca941451a29466d7a83f7d7fc26cf5ccf0b Mon Sep 17 00:00:00 2001 From: Topvennie Date: Tue, 19 Nov 2024 12:50:53 +0100 Subject: [PATCH 2/3] vinvoor: lint & format update --- .githooks/pre-commit | 16 + .githooks/vinvoor_format_lint | 20 - .../{vinvoor_format_lint.yml => vinvoor.yml} | 20 +- vinvoor/.eslintrc.cjs | 18 - vinvoor/.prettierrc | 4 - vinvoor/eslint.config.mjs | 42 +- vinvoor/package.json | 6 +- vinvoor/pnpm-lock.yaml | 842 +++++++++++++++++- vinvoor/src/App.tsx | 34 +- vinvoor/src/WelcomePage.tsx | 6 +- vinvoor/src/auth/Login.tsx | 7 +- vinvoor/src/auth/Logout.tsx | 7 +- vinvoor/src/cards/Cards.tsx | 4 +- vinvoor/src/cards/CardsAdd.tsx | 60 +- vinvoor/src/cards/CardsDelete.tsx | 16 +- vinvoor/src/cards/CardsEmpty.tsx | 4 +- vinvoor/src/cards/CardsTable.tsx | 67 +- vinvoor/src/cards/CardsTableBody.tsx | 15 +- vinvoor/src/cards/CardsTableHead.tsx | 11 +- vinvoor/src/cards/CardsTableToolbar.tsx | 44 +- vinvoor/src/cards/CircularTimeProgress.tsx | 2 +- vinvoor/src/components/BrowserView.tsx | 9 +- vinvoor/src/components/DarkModeToggle.tsx | 4 +- vinvoor/src/components/LoadingSkeleton.tsx | 14 +- vinvoor/src/components/ProtectedRoute.tsx | 5 +- vinvoor/src/components/TypographyG.tsx | 7 +- vinvoor/src/components/UnstyledLink.tsx | 7 +- vinvoor/src/errors/ErrorPage.tsx | 17 +- vinvoor/src/footer/Footer.tsx | 9 +- vinvoor/src/hooks/admin/useAdminDays.ts | 26 +- vinvoor/src/hooks/admin/useAdminSeason.ts | 25 +- vinvoor/src/hooks/useCard.ts | 16 +- vinvoor/src/hooks/useLeaderboard.ts | 15 +- vinvoor/src/hooks/useScan.ts | 10 +- vinvoor/src/hooks/useSeasons.ts | 16 +- vinvoor/src/hooks/useSettings.ts | 18 +- vinvoor/src/hooks/useUser.ts | 19 +- vinvoor/src/hooks/useVersion.ts | 10 +- vinvoor/src/leaderboard/Leaderboard.tsx | 6 +- .../src/leaderboard/LeaderboardTableBody.tsx | 40 +- .../leaderboard/LeaderboardTableToolbar.tsx | 4 +- vinvoor/src/main.tsx | 18 +- vinvoor/src/navbar/NavBar.tsx | 4 +- vinvoor/src/navbar/NavBarLogo.tsx | 19 +- vinvoor/src/navbar/NavBarPages.tsx | 7 +- vinvoor/src/navbar/NavBarSandwich.tsx | 11 +- vinvoor/src/navbar/NavBarSeasons.tsx | 11 +- vinvoor/src/navbar/NavBarUserMenu.tsx | 193 ++-- vinvoor/src/overview/Overview.tsx | 141 +-- vinvoor/src/overview/checkin/CheckIn.tsx | 49 +- vinvoor/src/overview/days/Days.tsx | 17 +- vinvoor/src/overview/heatmap/Day.tsx | 177 ++-- vinvoor/src/overview/heatmap/Heatmap.tsx | 14 +- vinvoor/src/overview/heatmap/LabelsMonth.tsx | 13 +- vinvoor/src/overview/heatmap/Rect.tsx | 4 +- vinvoor/src/overview/heatmap/utils.ts | 56 +- vinvoor/src/overview/streak/Streak.tsx | 105 ++- .../src/providers/CustomSnackbarProvider.tsx | 6 +- vinvoor/src/providers/ThemeProvider.tsx | 9 +- vinvoor/src/scans/Scans.tsx | 8 +- vinvoor/src/scans/ScansTableBody.tsx | 17 +- vinvoor/src/scans/ScansTableHead.tsx | 4 +- vinvoor/src/settings/Settings.tsx | 22 +- vinvoor/src/settings/SettingsOverview.tsx | 4 +- vinvoor/src/settings/admin/Admin.tsx | 2 +- vinvoor/src/settings/admin/days/Days.tsx | 6 +- vinvoor/src/settings/admin/days/DaysAdd.tsx | 10 +- vinvoor/src/settings/admin/days/DaysTable.tsx | 50 +- .../src/settings/admin/days/DaysTableBody.tsx | 8 +- .../src/settings/admin/days/DaysTableHead.tsx | 10 +- .../settings/admin/days/DaysTableToolbar.tsx | 32 +- .../src/settings/admin/seasons/Seasons.tsx | 8 +- .../src/settings/admin/seasons/SeasonsAdd.tsx | 20 +- .../settings/admin/seasons/SeasonsTable.tsx | 24 +- .../admin/seasons/SeasonsTableBody.tsx | 13 +- .../admin/seasons/SeasonsTableHead.tsx | 10 +- vinvoor/src/themes/theme.ts | 5 +- vinvoor/src/types/cards.ts | 36 +- vinvoor/src/types/days.ts | 7 +- vinvoor/src/types/leaderboard.ts | 9 +- vinvoor/src/types/scans.ts | 17 +- vinvoor/src/types/seasons.ts | 7 +- vinvoor/src/types/settings.ts | 8 +- vinvoor/src/types/version.ts | 8 +- vinvoor/src/util/fetch.ts | 62 +- vinvoor/src/util/util.ts | 50 +- vinvoor/tsconfig.json | 32 +- vinvoor/tsconfig.node.json | 4 +- 88 files changed, 1898 insertions(+), 971 deletions(-) create mode 100755 .githooks/pre-commit delete mode 100644 .githooks/vinvoor_format_lint rename .github/workflows/{vinvoor_format_lint.yml => vinvoor.yml} (54%) delete mode 100644 vinvoor/.eslintrc.cjs delete mode 100644 vinvoor/.prettierrc diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..0284a7a --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# some (*)nix distros dont have /bin/bash + +echo "Frontend linting" +(cd vinvoor && pnpm --silent run precommit:lint) +if [ $? -ne 0 ]; then + echo "Frontend linting failed. Please fix the errors before committing." + exit 1 +fi + +echo "Frontend typecheck" +(cd vinvoor && pnpm --silent run precommit:typecheck) +if [ $? -ne 0 ]; then + echo "Frontend type checking failed. Please fix the errors before committing." + exit 1 +fi diff --git a/.githooks/vinvoor_format_lint b/.githooks/vinvoor_format_lint deleted file mode 100644 index 41ecf78..0000000 --- a/.githooks/vinvoor_format_lint +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -# some (*)nix distros dont have /bin/bash - -cd vinvoor/ - -pnpm run format - -if [ $? -ne 0 ]; then - echo "Error: code improperly formatted!" - exit 1 -fi - -pnpm run lint - -if [ $? -ne 0 ]; then - echo "Error: code improperly linted!" - exit 1 -fi - -exit 0 diff --git a/.github/workflows/vinvoor_format_lint.yml b/.github/workflows/vinvoor.yml similarity index 54% rename from .github/workflows/vinvoor_format_lint.yml rename to .github/workflows/vinvoor.yml index 3195e8f..b740f45 100644 --- a/.github/workflows/vinvoor_format_lint.yml +++ b/.github/workflows/vinvoor.yml @@ -1,16 +1,10 @@ -name: Format and linting +name: Vinvoor Format, Lint & Typecheck on: push: branches: - main - paths: - - .github/workflows/vinvoor_format_lint.yml - - 'vinvoor/**' pull_request: - paths: - - .github/workflows/vinvoor_format_lint.yml - - 'vinvoor/**' jobs: format-and-lint: @@ -20,10 +14,10 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Node.js + - name: Setup Node.js uses: actions/setup-node@v3 with: - node-version: 20.15.1 + node-version: 22.8.0 - name: Install pnpm run: npm install -g pnpm @@ -32,10 +26,10 @@ jobs: run: pnpm install working-directory: vinvoor/ - - name: Run formatter - run: pnpm prettier --check . + - name: Run format & lint + run: pnpm eslint . working-directory: vinvoor/ - - name: Run Linter - run: pnpm eslint . --max-warnings=0 + - name: Run typecheck + run: pnpm tsc --noEmit working-directory: vinvoor/ diff --git a/vinvoor/.eslintrc.cjs b/vinvoor/.eslintrc.cjs deleted file mode 100644 index 6e8698b..0000000 --- a/vinvoor/.eslintrc.cjs +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - root: true, - env: { browser: true, es2020: true }, - extends: [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:react-hooks/recommended", - ], - ignorePatterns: ["dist", ".eslintrc.cjs"], - parser: "@typescript-eslint/parser", - plugins: ["react-refresh"], - rules: { - "react-refresh/only-export-components": [ - "warn", - { allowConstantExport: true }, - ], - }, -}; diff --git a/vinvoor/.prettierrc b/vinvoor/.prettierrc deleted file mode 100644 index aa7dddc..0000000 --- a/vinvoor/.prettierrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "tabWidth": 2, - "arrowParens": "avoid" -} diff --git a/vinvoor/eslint.config.mjs b/vinvoor/eslint.config.mjs index aadd73b..82a73a5 100644 --- a/vinvoor/eslint.config.mjs +++ b/vinvoor/eslint.config.mjs @@ -1,28 +1,24 @@ -import { includeIgnoreFile } from "@eslint/compat"; -import eslint from "@eslint/js"; -import eslintConfigPrettier from "eslint-config-prettier"; -import path, { dirname } from "node:path"; -import { fileURLToPath } from "node:url"; -import tseslint from "typescript-eslint"; +import antfu from "@antfu/eslint-config"; -const __dirname = dirname(fileURLToPath(import.meta.url)); -const gitignorePath = path.resolve(__dirname, ".gitignore"); - -export default tseslint.config( - eslint.configs.recommended, - ...tseslint.configs.recommendedTypeChecked, - ...tseslint.configs.stylisticTypeChecked, - includeIgnoreFile(gitignorePath), +export default antfu( { - languageOptions: { - parserOptions: { - projectService: true, - tsconfigRootDir: __dirname, - }, + stylistic: { + quotes: "double", + semi: true, + }, + + react: true, + + typescript: { + tsconfigPath: "./tsconfig.json", + }, + + formatters: true, + + rules: { + "react-hooks/exhaustive-deps": "off", + "ts/switch-exhaustiveness-check": "off", + "ts/strict-boolean-expressions": "off", }, }, - { - ignores: ["eslint.config.mjs", ".eslintrc.cjs"], - }, - eslintConfigPrettier, ); diff --git a/vinvoor/package.json b/vinvoor/package.json index 7380f4c..edac4b6 100644 --- a/vinvoor/package.json +++ b/vinvoor/package.json @@ -1,8 +1,8 @@ { "name": "vinvoor", - "private": true, - "version": "0.0.0", "type": "module", + "version": "0.0.0", + "private": true, "scripts": { "dev": "vite", "host": "vite --host", @@ -42,8 +42,6 @@ "@types/node": "^22.9.0", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", - "@typescript-eslint/eslint-plugin": "^7.18.0", - "@typescript-eslint/parser": "^7.18.0", "@vitejs/plugin-react-swc": "^3.7.1", "eslint": "^9.15.0", "eslint-config-prettier": "^9.1.0", diff --git a/vinvoor/pnpm-lock.yaml b/vinvoor/pnpm-lock.yaml index 8784dcb..fdd5c01 100644 --- a/vinvoor/pnpm-lock.yaml +++ b/vinvoor/pnpm-lock.yaml @@ -1120,6 +1120,10 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1240,7 +1244,162 @@ packages: resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} engines: {node: '>=10'} peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + eslint: '>=6.0.0' + + eslint-compat-utils@0.6.3: + resolution: {integrity: sha512-9IDdksh5pUYP2ZLi7mOdROxVjLY8gY2qKxprmrJ/5Dyqud7M/IFKxF3o0VLlRhITm1pK6Fk7NiBxE39M/VlUcw==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + + eslint-config-flat-gitignore@0.3.0: + resolution: {integrity: sha512-0Ndxo4qGhcewjTzw52TK06Mc00aDtHNTdeeW2JfONgDcLkRO/n/BteMRzNVpLQYxdCC/dFEilfM9fjjpGIJ9Og==} + peerDependencies: + eslint: ^9.5.0 + + eslint-flat-config-utils@0.4.0: + resolution: {integrity: sha512-kfd5kQZC+BMO0YwTol6zxjKX1zAsk8JfSAopbKjKqmENTJcew+yBejuvccAg37cvOrN0Mh+DVbeyznuNWEjt4A==} + + eslint-formatting-reporter@0.0.0: + resolution: {integrity: sha512-k9RdyTqxqN/wNYVaTk/ds5B5rA8lgoAmvceYN7bcZMBwU7TuXx5ntewJv81eF3pIL/CiJE+pJZm36llG8yhyyw==} + peerDependencies: + eslint: '>=8.40.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-json-compat-utils@0.2.1: + resolution: {integrity: sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==} + engines: {node: '>=12'} + peerDependencies: + '@eslint/json': '*' + eslint: '*' + jsonc-eslint-parser: ^2.4.0 + peerDependenciesMeta: + '@eslint/json': + optional: true + + eslint-merge-processors@0.1.0: + resolution: {integrity: sha512-IvRXXtEajLeyssvW4wJcZ2etxkR9mUf4zpNwgI+m/Uac9RfXHskuJefkHUcawVzePnd6xp24enp5jfgdHzjRdQ==} + peerDependencies: + eslint: '*' + + eslint-parser-plain@0.1.0: + resolution: {integrity: sha512-oOeA6FWU0UJT/Rxc3XF5Cq0nbIZbylm7j8+plqq0CZoE6m4u32OXJrR+9iy4srGMmF6v6pmgvP1zPxSRIGh3sg==} + + eslint-plugin-antfu@2.7.0: + resolution: {integrity: sha512-gZM3jq3ouqaoHmUNszb1Zo2Ux7RckSvkGksjLWz9ipBYGSv1EwwBETN6AdiUXn+RpVHXTbEMPAPlXJazcA6+iA==} + peerDependencies: + eslint: '*' + + eslint-plugin-command@0.2.6: + resolution: {integrity: sha512-T0bHZ1oblW1xUHUVoBKZJR2osSNNGkfZuK4iqboNwuNS/M7tdp3pmURaJtTi/XDzitxaQ02lvOdFH0mUd5QLvQ==} + peerDependencies: + eslint: '*' + + eslint-plugin-es-x@7.8.0: + resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + + eslint-plugin-format@0.1.2: + resolution: {integrity: sha512-ZrcO3aiumgJ6ENAv65IWkPjtW77ML/5mp0YrRK0jdvvaZJb+4kKWbaQTMr/XbJo6CtELRmCApAziEKh7L2NbdQ==} + peerDependencies: + eslint: ^8.40.0 || ^9.0.0 + + eslint-plugin-import-x@4.4.2: + resolution: {integrity: sha512-mDRXPSLQ0UQZQw91QdG4/qZT6hgeW2MJTczAbgPseUZuPEtIjjdPOolXroRkulnOn3fzj6gNgvk+wchMJiHElg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + eslint-plugin-jsdoc@50.5.0: + resolution: {integrity: sha512-xTkshfZrUbiSHXBwZ/9d5ulZ2OcHXxSvm/NPo494H/hadLRJwOq5PMV0EUpMqsb9V+kQo+9BAgi6Z7aJtdBp2A==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-plugin-jsonc@2.18.2: + resolution: {integrity: sha512-SDhJiSsWt3nItl/UuIv+ti4g3m4gpGkmnUJS9UWR3TrpyNsIcnJoBRD7Kof6cM4Rk3L0wrmY5Tm3z7ZPjR2uGg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + eslint-plugin-n@17.13.2: + resolution: {integrity: sha512-MhBAKkT01h8cOXcTBTlpuR7bxH5OBUNpUXefsvwSVEy46cY4m/Kzr2osUCQvA3zJFD6KuCeNNDv0+HDuWk/OcA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.23.0' + + eslint-plugin-no-only-tests@3.3.0: + resolution: {integrity: sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==} + engines: {node: '>=5.0.0'} + + eslint-plugin-perfectionist@3.9.1: + resolution: {integrity: sha512-9WRzf6XaAxF4Oi5t/3TqKP5zUjERhasHmLFHin2Yw6ZAp/EP/EVA2dr3BhQrrHWCm5SzTMZf0FcjDnBkO2xFkA==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + astro-eslint-parser: ^1.0.2 + eslint: '>=8.0.0' + svelte: '>=3.0.0' + svelte-eslint-parser: ^0.41.1 + vue-eslint-parser: '>=9.0.0' + peerDependenciesMeta: + astro-eslint-parser: + optional: true + svelte: + optional: true + svelte-eslint-parser: + optional: true + vue-eslint-parser: + optional: true + + eslint-plugin-react-debug@1.16.1: + resolution: {integrity: sha512-AijumibZ+3hBYCGBEeD3GQse5TPnq9z6bX0qfsFwCwWjkW+siL2EEGvaxT7UZp2mcFMvoRJT3E4Jsemn6g0AGw==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + eslint-plugin-react-dom@1.16.1: + resolution: {integrity: sha512-qJFfCR2Rofd5/V9/8EE4sg6a829HcI07DeK7qqTosYRPBYkwbfUUjvizzlTxneMAcPQuFfPZa1UMDTaejKStyg==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + eslint-plugin-react-hooks-extra@1.16.1: + resolution: {integrity: sha512-OJ4RJZ7n25XnF6+NaFC9dzrec2C+/o4zb4Brs+v6fVVbvQQZirgWamKZMOJo+I1HsHdOULtBo1uwopLfnVBihQ==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + eslint-plugin-react-hooks@5.1.0-beta-26f2496093-20240514: + resolution: {integrity: sha512-nCZD93/KYY5hNAWGhfvvrEXvLFIXJCMu2St7ciHeiWUp/lnS2RVgWawp2kNQamr9Y23C9lUA03TmDRNgbm05vg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-naming-convention@1.16.1: + resolution: {integrity: sha512-qyZ6YW82vLHHQEboc0LhE+9Uga2koCtwEV0XYEWxq3DI3Wg1SlwsfchPYQc7skRh2c/Jh9YG2gzRmNXG4Ul2Ww==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true eslint-plugin-react-refresh@0.4.14: resolution: {integrity: sha512-aXvzCTK7ZBv1e7fahFuR3Z/fyQQSIQ711yPgYRj+Oj64tyTgO4iQIDmYXDBqvSWQ/FA4OSCsXOStlF+noU0/NA==} @@ -1367,6 +1526,9 @@ packages: peerDependencies: csstype: ^3.0.10 + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -1448,6 +1610,10 @@ packages: engines: {node: '>=6'} hasBin: true + jsonc-eslint-parser@2.4.0: + resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1482,6 +1648,39 @@ packages: react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 + mdast-util-find-and-replace@3.0.1: + resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.0.0: + resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.0.0: + resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + mdi-material-ui@7.9.2: resolution: {integrity: sha512-MZ5zxN7W6yqtHwNYtV/Ezt6nQtMPsA3UtHcNpHwSDbFdvWgspTKyxh4gS63G8e49qyJAPdq0JMjxV3SEnXu4yQ==} peerDependencies: @@ -1511,6 +1710,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -1527,6 +1729,9 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -1791,6 +1996,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -1839,6 +2047,12 @@ packages: terser: optional: true + vue-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -2730,7 +2944,6 @@ snapshots: eslint: 9.15.0 transitivePeerDependencies: - supports-color - - typescript '@typescript-eslint/utils@8.15.0(eslint@9.15.0)(typescript@5.6.3)': dependencies: @@ -2776,6 +2989,8 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-regex@5.0.1: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 @@ -2790,9 +3005,9 @@ snapshots: svg.resize.js: 1.4.3 svg.select.js: 3.0.1 - argparse@2.0.1: {} + are-docs-informative@0.0.2: {} - array-union@2.1.0: {} + argparse@2.0.1: {} babel-plugin-macros@3.1.0: dependencies: @@ -2802,6 +3017,10 @@ snapshots: balanced-match@1.0.2: {} + birecord@0.1.1: {} + + boolbase@1.0.0: {} + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -2822,6 +3041,8 @@ snapshots: node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.2) + builtin-modules@3.3.0: {} + callsites@3.1.0: {} camelcase@6.3.0: {} @@ -2833,8 +3054,22 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + character-entities@2.0.2: {} + + ci-info@4.1.0: {} + classnames@2.5.1: {} + clean-regexp@1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + clsx@1.2.1: {} clsx@2.1.1: {} @@ -2845,12 +3080,20 @@ snapshots: color-name@1.1.4: {} + comment-parser@1.4.1: {} + concat-map@0.0.1: {} + confbox@0.1.8: {} + convert-source-map@1.9.0: {} convert-source-map@2.0.0: {} + core-js-compat@3.39.0: + dependencies: + browserslist: 4.24.2 + cosmiconfig@7.1.0: dependencies: '@types/parse-json': 4.0.2 @@ -2874,19 +3117,35 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + cssesc@3.0.0: {} + csstype@3.1.3: {} dayjs@1.11.13: {} + debug@3.2.7: + dependencies: + ms: 2.1.3 + debug@4.3.7: dependencies: ms: 2.1.3 + decode-named-character-reference@1.0.2: + dependencies: + character-entities: 2.0.2 + deep-is@0.1.4: {} - dir-glob@3.0.1: + dequal@2.0.3: {} + + devlop@1.1.0: dependencies: - path-type: 4.0.0 + dequal: 2.0.3 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 dom-helpers@5.2.1: dependencies: @@ -2906,6 +3165,8 @@ snapshots: dependencies: is-arrayish: 0.2.1 + es-module-lexer@1.5.4: {} + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -2934,6 +3195,8 @@ snapshots: escalade@3.2.0: {} + escape-string-regexp@1.0.5: {} + escape-string-regexp@4.0.0: {} eslint-config-prettier@9.1.0(eslint@9.15.0): @@ -3018,6 +3281,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-diff@1.3.0: {} + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3044,6 +3309,13 @@ snapshots: find-root@1.1.0: {} + find-up-simple@1.0.0: {} + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -3063,6 +3335,12 @@ snapshots: gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + + get-tsconfig@4.8.1: + dependencies: + resolve-pkg-maps: 1.0.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -3073,21 +3351,20 @@ snapshots: globals@11.12.0: {} + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + globals@14.0.0: {} - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 + globals@15.12.0: {} goober@2.1.16(csstype@3.1.3): dependencies: csstype: 3.1.3 + graceful-fs@4.2.11: {} + graphemer@1.4.0: {} has-flag@4.0.0: {} @@ -3100,6 +3377,8 @@ snapshots: dependencies: react-is: 16.13.1 + hosted-git-info@2.8.9: {} + ignore@5.3.2: {} import-fresh@3.3.0: @@ -3109,18 +3388,36 @@ snapshots: imurmurhash@0.1.4: {} + indent-string@4.0.0: {} + is-arrayish@0.2.1: {} + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + is-core-module@2.15.1: dependencies: hasown: 2.0.2 is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + is-immutable-type@5.0.0(eslint@9.15.0)(typescript@5.6.3): + dependencies: + '@typescript-eslint/type-utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + eslint: 9.15.0 + ts-api-utils: 1.4.0(typescript@5.6.3) + ts-declaration-location: 1.0.4(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + is-number@7.0.0: {} isexe@2.0.0: {} @@ -3133,6 +3430,10 @@ snapshots: dependencies: argparse: 2.0.1 + jsdoc-type-pratt-parser@4.1.0: {} + + jsesc@0.5.0: {} + jsesc@3.0.2: {} json-buffer@3.0.1: {} @@ -3145,6 +3446,13 @@ snapshots: json5@2.2.3: {} + jsonc-eslint-parser@2.4.0: + dependencies: + acorn: 8.14.0 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + semver: 7.6.3 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -3156,12 +3464,25 @@ snapshots: lines-and-columns@1.2.4: {} + local-pkg@0.5.1: + dependencies: + mlly: 1.7.3 + pkg-types: 1.2.1 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + locate-path@6.0.0: dependencies: p-locate: 5.0.0 lodash.merge@4.6.2: {} + lodash@4.17.21: {} + + longest-streak@3.1.0: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -3174,12 +3495,120 @@ snapshots: dependencies: yallist: 3.1.1 + magic-string@0.30.13: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + markdown-table@3.0.4: {} + material-ui-confirm@3.0.16(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@mui/material': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + mdast-util-find-and-replace@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.1 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + 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.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.0 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdi-material-ui@7.9.2(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): dependencies: '@mui/material': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -3187,11 +3616,208 @@ snapshots: merge2@1.4.1: {} + micromark-core-commonmark@2.0.2: + dependencies: + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.0.2 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.2 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-table@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.1 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.0 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.1 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.1 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.0.2: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.1: {} + + micromark@4.0.1: + dependencies: + '@types/debug': 4.1.12 + debug: 4.3.7 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.2 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.0.2 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 picomatch: 2.3.1 + min-indent@1.0.1: {} + + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -3200,10 +3826,19 @@ snapshots: dependencies: brace-expansion: 2.0.1 + mlly@1.7.3: + dependencies: + acorn: 8.14.0 + pathe: 1.1.2 + pkg-types: 1.2.1 + ufo: 1.5.4 + ms@2.1.3: {} nanoid@3.3.7: {} + natural-compare-lite@1.4.0: {} + natural-compare@1.4.0: {} no-case@3.0.4: @@ -3213,6 +3848,13 @@ snapshots: node-releases@2.0.18: {} + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + notistack@3.0.1(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: clsx: 1.2.1 @@ -3222,6 +3864,10 @@ snapshots: transitivePeerDependencies: - csstype + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + object-assign@4.1.1: {} optionator@0.9.4: @@ -3233,18 +3879,37 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 + p-try@2.2.0: {} + + package-manager-detector@0.2.4: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 + parse-gitignore@2.0.0: {} + + parse-imports@2.2.1: + dependencies: + es-module-lexer: 1.5.4 + slashes: 3.0.12 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.26.2 @@ -3260,6 +3925,8 @@ snapshots: path-type@4.0.0: {} + pathe@1.1.2: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -3274,6 +3941,10 @@ snapshots: prelude-ls@1.2.1: {} + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + prettier@3.3.3: {} prop-types@15.8.1: @@ -3340,10 +4011,42 @@ snapshots: dependencies: loose-envify: 1.4.0 + read-pkg-up@7.0.1: + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + + read-pkg@5.2.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + + refa@0.12.1: + dependencies: + '@eslint-community/regexpp': 4.12.1 + regenerator-runtime@0.14.1: {} + regexp-ast-analysis@0.7.1: + dependencies: + '@eslint-community/regexpp': 4.12.1 + refa: 0.12.1 + + regexp-tree@0.1.27: {} + + regjsparser@0.10.0: + dependencies: + jsesc: 0.5.0 + + require-directory@2.1.1: {} + resolve-from@4.0.0: {} + resolve-pkg-maps@1.0.0: {} + resolve@1.22.8: dependencies: is-core-module: 2.15.1 @@ -3384,6 +4087,14 @@ snapshots: dependencies: loose-envify: 1.4.0 + scslre@0.3.0: + dependencies: + '@eslint-community/regexpp': 4.12.1 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + + semver@5.7.2: {} + semver@6.3.1: {} semver@7.6.3: {} @@ -3405,6 +4116,43 @@ snapshots: source-map@0.5.7: {} + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.20 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.20 + + spdx-expression-parse@4.0.0: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.20 + + spdx-license-ids@3.0.20: {} + + stable-hash@0.0.4: {} + + string-ts@2.2.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + strip-json-comments@3.1.1: {} stylis@4.2.0: {} @@ -3475,8 +4223,29 @@ snapshots: typescript@5.6.3: {} + ufo@1.5.4: {} + undici-types@6.19.8: {} + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + update-browserslist-db@1.1.1(browserslist@4.24.2): dependencies: browserslist: 4.24.2 @@ -3507,14 +4276,59 @@ snapshots: '@types/node': 22.9.0 fsevents: 2.3.3 + vue-eslint-parser@9.4.3(eslint@9.15.0): + dependencies: + debug: 4.3.7 + eslint: 9.15.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + lodash: 4.17.21 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + which@2.0.2: dependencies: isexe: 2.0.0 word-wrap@1.2.5: {} + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + xml-name-validator@4.0.0: {} + + y18n@5.0.8: {} + yallist@3.1.1: {} + yaml-eslint-parser@1.2.3: + dependencies: + eslint-visitor-keys: 3.4.3 + lodash: 4.17.21 + yaml: 2.6.0 + yaml@1.10.2: {} + yaml@2.6.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + yocto-queue@0.1.0: {} + + zwitch@2.0.4: {} diff --git a/vinvoor/src/App.tsx b/vinvoor/src/App.tsx index 27477c6..d667b00 100644 --- a/vinvoor/src/App.tsx +++ b/vinvoor/src/App.tsx @@ -6,11 +6,11 @@ import { Footer } from "./footer/Footer"; import { useUser } from "./hooks/useUser"; import { NavBar } from "./navbar/NavBar"; import { Overview } from "./overview/Overview"; -import "./themes/background.css"; import { randomInt } from "./util/util"; import { WelcomePage } from "./WelcomePage"; +import "./themes/background.css"; -export const App = () => { +export function App() { const userQuery = useUser(); const outlet = useOutlet(); @@ -34,18 +34,22 @@ export const App = () => { }} > - {Object.keys(userQuery.data ?? {}).length > 0 ? ( - outlet !== null ? ( - - ) : ( - - ) - ) : ( - <> - - - - )} + {Object.keys(userQuery.data ?? {}).length > 0 + ? ( + outlet !== null + ? ( + + ) + : ( + + ) + ) + : ( + <> + + + + )} @@ -53,4 +57,4 @@ export const App = () => { ); -}; +} diff --git a/vinvoor/src/WelcomePage.tsx b/vinvoor/src/WelcomePage.tsx index 2113ed7..52efd46 100644 --- a/vinvoor/src/WelcomePage.tsx +++ b/vinvoor/src/WelcomePage.tsx @@ -1,8 +1,8 @@ import { GitHub } from "@mui/icons-material"; import { Box, Button, Typography } from "@mui/material"; import { ShakerOutline } from "mdi-material-ui"; -import { TypographyG } from "./components/TypographyG"; import { Login } from "./auth/Login"; +import { TypographyG } from "./components/TypographyG"; declare module "@mui/material/Button" { interface ButtonPropsColorOverrides { @@ -10,7 +10,7 @@ declare module "@mui/material/Button" { } } -export const WelcomePage = () => { +export function WelcomePage() { const handleClick = () => { window.location.replace("https://github.com/ZeusWPI/ZeSS"); }; @@ -46,4 +46,4 @@ export const WelcomePage = () => { ); -}; +} diff --git a/vinvoor/src/auth/Login.tsx b/vinvoor/src/auth/Login.tsx index d8a48e9..591ea76 100644 --- a/vinvoor/src/auth/Login.tsx +++ b/vinvoor/src/auth/Login.tsx @@ -1,7 +1,8 @@ -import { Button, ButtonProps } from "@mui/material"; -import { FC } from "react"; +import type { ButtonProps } from "@mui/material"; +import type { FC } from "react"; +import { Button } from "@mui/material"; -export const Login: FC = props => { +export const Login: FC = (props) => { const url = import.meta.env.VITE_BACKEND_URL as string; const handleClick = () => { diff --git a/vinvoor/src/auth/Logout.tsx b/vinvoor/src/auth/Logout.tsx index c5fb8c3..c3a3b3c 100644 --- a/vinvoor/src/auth/Logout.tsx +++ b/vinvoor/src/auth/Logout.tsx @@ -1,8 +1,9 @@ -import { Button, ButtonProps } from "@mui/material"; -import { FC } from "react"; +import type { ButtonProps } from "@mui/material"; +import type { FC } from "react"; +import { Button } from "@mui/material"; import { useLogout } from "../hooks/useUser"; -export const Logout: FC = props => { +export const Logout: FC = (props) => { const logout = useLogout(); const handleClick = () => { logout.mutate(); diff --git a/vinvoor/src/cards/Cards.tsx b/vinvoor/src/cards/Cards.tsx index f46cdf6..8083d4c 100644 --- a/vinvoor/src/cards/Cards.tsx +++ b/vinvoor/src/cards/Cards.tsx @@ -3,7 +3,7 @@ import { useCards } from "../hooks/useCard"; import { CardsEmpty } from "./CardsEmpty"; import { CardsTable } from "./CardsTable"; -export const Cards = () => { +export function Cards() { const cardsQuery = useCards(); return ( @@ -11,4 +11,4 @@ export const Cards = () => { {cardsQuery.data?.length ? : } ); -}; +} diff --git a/vinvoor/src/cards/CardsAdd.tsx b/vinvoor/src/cards/CardsAdd.tsx index 36826c2..b070df3 100644 --- a/vinvoor/src/cards/CardsAdd.tsx +++ b/vinvoor/src/cards/CardsAdd.tsx @@ -1,24 +1,28 @@ +import type { + CardGetRegisterResponse, + CardGetRegisterResponseJSON, + CardPostResponse, + CardPostResponseJSON, +} from "../types/cards"; +import type { Optional } from "../types/general"; +import type { + CircularTimeProgressProps, +} from "./CircularTimeProgress"; import { Add } from "@mui/icons-material"; import { Button, Typography } from "@mui/material"; import { useConfirm } from "material-ui-confirm"; import { useSnackbar } from "notistack"; import { useEffect, useState } from "react"; +import { useCards } from "../hooks/useCard"; import { - CardGetRegisterResponse, - CardGetRegisterResponseJSON, - CardPostResponse, - CardPostResponseJSON, convertCardGetRegisterResponseJSON, convertCardPostResponseJSON, } from "../types/cards"; -import { Optional } from "../types/general"; import { getApi, isResponseNot200Error, postApi } from "../util/fetch"; import { randomInt } from "../util/util"; import { CircularTimeProgress, - CircularTimeProgressProps, } from "./CircularTimeProgress"; -import { useCards } from "../hooks/useCard"; const CHECK_INTERVAL = 1000; const REGISTER_TIME = 60000; @@ -37,19 +41,19 @@ const confirmContent = ` const requestSuccess = "Register your card by holding it to vinscant"; const requestYou = "You are already registering a card!"; -const requestOther = - "Failed to start the card registering process because another user is already registering a card. Please try again later."; -const requestFail = - "Failed to start the card registration process. Please try again later or contact a sysadmin"; +const requestOther + = "Failed to start the card registering process because another user is already registering a card. Please try again later."; +const requestFail + = "Failed to start the card registration process. Please try again later or contact a sysadmin"; const registerSucces = "Card registered successfully"; const registerFail = "Failed to register card"; -export const CardsAdd = () => { +export function CardsAdd() { const { refetch } = useCards(); const [registering, setRegistering] = useState(false); - const [progressProps, setProgressProps] = - useState(defaultProgressProps); + const [progressProps, setProgressProps] + = useState(defaultProgressProps); const confirm = useConfirm(); const { enqueueSnackbar, closeSnackbar } = useSnackbar(); @@ -78,7 +82,7 @@ export const CardsAdd = () => { REGISTER_ENDPOINT, convertCardGetRegisterResponseJSON, ) - .then(async response => { + .then(async (response) => { let started = false; if (!response.registering && start) { await postApi( @@ -87,25 +91,31 @@ export const CardsAdd = () => { convertCardPostResponseJSON, ) .then(() => (started = true)) - .catch(error => { + .catch((error) => { if (isResponseNot200Error(error)) { void error.response .json() .then((response: CardPostResponse) => { - if (response.isCurrentUser) + if (response.isCurrentUser) { enqueueSnackbar(requestYou, { variant: "warning", }); - else + } + else { enqueueSnackbar(requestOther, { variant: "error", }); + } }); - } else throw new Error(error as string); + } + else { + throw new Error(error as string); + } }); } - if (response.registering && response.isCurrentUser) started = true; + if (response.registering && response.isCurrentUser) + started = true; if (started) { setRegistering(true); @@ -121,9 +131,9 @@ export const CardsAdd = () => { } void checkCardsChange() - .then(scanned => { + .then((scanned) => { setRegistering(false); - if (id) { + if (id !== undefined) { closeSnackbar(id); if (scanned) { @@ -131,10 +141,12 @@ export const CardsAdd = () => { variant: "success", }); void refetch(); - } else + } + else { enqueueSnackbar(registerFail, { variant: "error", }); + } } }) .finally(() => setProgressProps(defaultProgressProps)); @@ -170,4 +182,4 @@ export const CardsAdd = () => { Register new card ); -}; +} diff --git a/vinvoor/src/cards/CardsDelete.tsx b/vinvoor/src/cards/CardsDelete.tsx index e16520a..0ee8ac5 100644 --- a/vinvoor/src/cards/CardsDelete.tsx +++ b/vinvoor/src/cards/CardsDelete.tsx @@ -1,8 +1,8 @@ +import type { FC } from "react"; import DeleteIcon from "@mui/icons-material/Delete"; import { IconButton, Link, Tooltip, Typography } from "@mui/material"; import { useConfirm } from "material-ui-confirm"; import { useSnackbar } from "notistack"; -import { FC } from "react"; interface CardDeleteProps { selected: readonly string[]; @@ -18,16 +18,22 @@ export const CardsDelete: FC = ({ selected }) => { const title = `Delete card${numSelected > 1 ? "s" : ""}`; const content = ( - Are you sure you want to delete {numSelected} card - {numSelected > 1 ? "s" : ""}? Unfortunately, this feature isn't available - yet. Let's convince Hannes to add this feature by signing this{" "} + Are you sure you want to delete + {" "} + {numSelected} + {" "} + card + {numSelected > 1 ? "s" : ""} + ? Unfortunately, this feature isn't available + yet. Let's convince Hannes to add this feature by signing this + {" "} petition! ); const handleClick = () => { void confirm({ - title: title, + title, description: content, confirmationText: "Delete", }).then(() => enqueueSnackbar(deletePressed, { variant: "error" })); diff --git a/vinvoor/src/cards/CardsEmpty.tsx b/vinvoor/src/cards/CardsEmpty.tsx index d936b52..6048cac 100644 --- a/vinvoor/src/cards/CardsEmpty.tsx +++ b/vinvoor/src/cards/CardsEmpty.tsx @@ -2,7 +2,7 @@ import { Paper } from "@mui/material"; import { TypographyG } from "../components/TypographyG"; import { CardsAdd } from "./CardsAdd"; -export const CardsEmpty = () => { +export function CardsEmpty() { return ( { ); -}; +} diff --git a/vinvoor/src/cards/CardsTable.tsx b/vinvoor/src/cards/CardsTable.tsx index 8f6c158..26efe70 100644 --- a/vinvoor/src/cards/CardsTable.tsx +++ b/vinvoor/src/cards/CardsTable.tsx @@ -1,37 +1,34 @@ +import type { ChangeEvent, MouseEvent } from "react"; +import type { Card } from "../types/cards"; +import type { TableOrder } from "../types/general"; import { Paper, Table, TableContainer, TablePagination } from "@mui/material"; -import { ChangeEvent, MouseEvent, useMemo, useState } from "react"; -import { Card } from "../types/cards"; -import { TableOrder } from "../types/general"; +import { useMemo, useState } from "react"; +import { useCards } from "../hooks/useCard"; import { CardsTableBody } from "./CardsTableBody"; import { CardsTableHead } from "./CardsTableHead"; import { CardsTableToolbar } from "./CardsTableToolbar"; -import { useCards } from "../hooks/useCard"; const rowsPerPageOptions = [10, 25, 50]; -const descendingComparator = (a: T, b: T, orderBy: keyof T) => { - if (b[orderBy] < a[orderBy]) return -1; - if (b[orderBy] > a[orderBy]) return 1; +function descendingComparator(a: T, b: T, orderBy: keyof T) { + if (b[orderBy] < a[orderBy]) + return -1; + if (b[orderBy] > a[orderBy]) + return 1; return 0; -}; +} -const getComparator = ( - order: TableOrder, - orderBy: Key, -): (( +function getComparator(order: TableOrder, orderBy: Key): (( a: Record, b: Record, -) => number) => { +) => number) { return order === "desc" ? (a, b) => descendingComparator(a, b, orderBy) : (a, b) => -descendingComparator(a, b, orderBy); -}; +} -const stableSort = ( - array: readonly T[], - comparator: (a: T, b: T) => number, -) => { +function stableSort(array: readonly T[], comparator: (a: T, b: T) => number) { const stabilized = array.map((el, index) => [el, index] as [T, number]); stabilized.sort((a, b) => { const order = comparator(a[0], b[0]); @@ -41,11 +38,10 @@ const stableSort = ( return a[1] - b[1]; }); return stabilized.map(el => el[0]); -}; +} -export const CardsTable = () => { +export function CardsTable() { const { data: cards } = useCards(); - if (!cards) return null; // Can never happen const [order, setOrder] = useState("asc"); const [orderBy, setOrderBy] = useState("serial"); @@ -53,6 +49,18 @@ export const CardsTable = () => { const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(10); + const visibleRows = useMemo( + () => + stableSort(cards ?? [], getComparator(order, orderBy)).slice( + page * rowsPerPage, + page * rowsPerPage + rowsPerPage, + ), + [cards, order, orderBy, page, rowsPerPage], + ); + + if (!cards) + return null; // Can never happen + const handleRequestSort = ( _: MouseEvent, property: keyof Card, @@ -106,23 +114,14 @@ export const CardsTable = () => { ) => setPage(newPage); const handleChangeRowsPerPage = (event: ChangeEvent) => { - setRowsPerPage(parseInt(event.target.value, 10)); + setRowsPerPage(Number.parseInt(event.target.value, 10)); setPage(0); }; const isSelected = (serial: string) => selected.includes(serial); - const emptyRows = - page > 0 ? Math.max(0, (1 + page) * rowsPerPage - cards.length) : 0; - - const visibleRows = useMemo( - () => - stableSort(cards, getComparator(order, orderBy)).slice( - page * rowsPerPage, - page * rowsPerPage + rowsPerPage, - ), - [cards, order, orderBy, page, rowsPerPage], - ); + const emptyRows + = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - cards.length) : 0; return ( @@ -156,4 +155,4 @@ export const CardsTable = () => { /> ); -}; +} diff --git a/vinvoor/src/cards/CardsTableBody.tsx b/vinvoor/src/cards/CardsTableBody.tsx index 1dfd2e4..2440e8b 100644 --- a/vinvoor/src/cards/CardsTableBody.tsx +++ b/vinvoor/src/cards/CardsTableBody.tsx @@ -1,3 +1,5 @@ +import type { ChangeEvent, FC, MouseEvent } from "react"; +import type { Card } from "../types/cards"; import { EditOutlined } from "@mui/icons-material"; import { Checkbox, @@ -10,9 +12,8 @@ import { } from "@mui/material"; import { useConfirm } from "material-ui-confirm"; import { useSnackbar } from "notistack"; -import { ChangeEvent, FC, MouseEvent } from "react"; -import { Card, cardsHeadCells } from "../types/cards"; import { useCards, usePatchCards } from "../hooks/useCard"; +import { cardsHeadCells } from "../types/cards"; interface CardsTableBodyProps { rows: readonly Card[]; @@ -47,9 +48,9 @@ export const CardsTableBody: FC = ({ variant="standard" defaultValue={name} onChange={(event: ChangeEvent) => - (newName = event.target.value) - } - > + (newName = event.target.value)} + > + ), confirmationText: "Save", }) @@ -60,7 +61,7 @@ export const CardsTableBody: FC = ({ } patchCard.mutate( - { id: id, newName: newName }, + { id, newName }, { onSuccess: () => { enqueueSnackbar(nameSaveSuccess, { @@ -86,7 +87,7 @@ export const CardsTableBody: FC = ({ return ( - {rows.map(row => { + {rows.map((row) => { const isSelected = isRowSelected(row.serial); return ( diff --git a/vinvoor/src/cards/CardsTableHead.tsx b/vinvoor/src/cards/CardsTableHead.tsx index 7a6fb8d..2eed412 100644 --- a/vinvoor/src/cards/CardsTableHead.tsx +++ b/vinvoor/src/cards/CardsTableHead.tsx @@ -1,3 +1,6 @@ +import type { ChangeEvent, FC, MouseEvent } from "react"; +import type { Card } from "../types/cards"; +import type { TableOrder } from "../types/general"; import { Checkbox, TableCell, @@ -6,9 +9,7 @@ import { TableSortLabel, Typography, } from "@mui/material"; -import { ChangeEvent, FC, MouseEvent } from "react"; -import { Card, cardsHeadCells } from "../types/cards"; -import { TableOrder } from "../types/general"; +import { cardsHeadCells } from "../types/cards"; interface CardTableHeadProps { numSelected: number; @@ -30,8 +31,8 @@ export const CardsTableHead: FC = ({ orderBy, rowCount, }) => { - const createSortHandler = - (property: keyof Card) => (event: MouseEvent) => + const createSortHandler + = (property: keyof Card) => (event: MouseEvent) => onRequestSort(event, property); return ( diff --git a/vinvoor/src/cards/CardsTableToolbar.tsx b/vinvoor/src/cards/CardsTableToolbar.tsx index 85413a3..ab98f5c 100644 --- a/vinvoor/src/cards/CardsTableToolbar.tsx +++ b/vinvoor/src/cards/CardsTableToolbar.tsx @@ -1,6 +1,6 @@ +import type { FC } from "react"; import { Toolbar, Typography } from "@mui/material"; import { alpha } from "@mui/material/styles"; -import { FC } from "react"; import { CardsAdd } from "./CardsAdd"; import { CardsDelete } from "./CardsDelete"; @@ -24,25 +24,29 @@ export const CardsTableToolbar: FC = ({ selected }) => { }), }} > - {numSelected > 0 ? ( - <> - - {numSelected} selected - - - - ) : ( - <> - - Cards - - - - )} + {numSelected > 0 + ? ( + <> + + {numSelected} + {" "} + selected + + + + ) + : ( + <> + + Cards + + + + )} ); }; diff --git a/vinvoor/src/cards/CircularTimeProgress.tsx b/vinvoor/src/cards/CircularTimeProgress.tsx index 6f274cc..fe0e39c 100644 --- a/vinvoor/src/cards/CircularTimeProgress.tsx +++ b/vinvoor/src/cards/CircularTimeProgress.tsx @@ -1,5 +1,5 @@ +import type { FC } from "react"; import { Box, CircularProgress, Typography } from "@mui/material"; -import { FC } from "react"; export interface CircularTimeProgressProps { time: number; diff --git a/vinvoor/src/components/BrowserView.tsx b/vinvoor/src/components/BrowserView.tsx index bf97481..a77e53f 100644 --- a/vinvoor/src/components/BrowserView.tsx +++ b/vinvoor/src/components/BrowserView.tsx @@ -1,5 +1,6 @@ +import type { FC } from "react"; import { useMediaQuery, useTheme } from "@mui/material"; -import { FC, useEffect } from "react"; +import { useEffect } from "react"; interface BrowserViewProps { onMobileView?: () => void; @@ -16,11 +17,13 @@ export const BrowserView: FC = ({ const isMobileView = useMediaQuery(theme.breakpoints.down("md")); useEffect(() => { - if (isMobileView) onMobileView?.(); + if (isMobileView) + onMobileView?.(); else onBrowserView?.(); }, [isMobileView]); - if (isMobileView) return null; + if (isMobileView) + return null; return isMobileView ? null : children; }; diff --git a/vinvoor/src/components/DarkModeToggle.tsx b/vinvoor/src/components/DarkModeToggle.tsx index 65858dc..13b9c30 100644 --- a/vinvoor/src/components/DarkModeToggle.tsx +++ b/vinvoor/src/components/DarkModeToggle.tsx @@ -3,7 +3,7 @@ import { IconButton, Tooltip } from "@mui/material"; import { useContext } from "react"; import { ThemeContext } from "../providers/ThemeProvider"; -export const DarkModeToggle = () => { +export function DarkModeToggle() { const { themeMode, setTheme } = useContext(ThemeContext); const handleThemeChange = () => @@ -19,4 +19,4 @@ export const DarkModeToggle = () => { ); -}; +} diff --git a/vinvoor/src/components/LoadingSkeleton.tsx b/vinvoor/src/components/LoadingSkeleton.tsx index ff2a7fa..c1bdcae 100644 --- a/vinvoor/src/components/LoadingSkeleton.tsx +++ b/vinvoor/src/components/LoadingSkeleton.tsx @@ -1,6 +1,7 @@ -import { Skeleton, SkeletonProps } from "@mui/material"; -import { UseQueryResult } from "@tanstack/react-query"; -import { FC, ReactNode } from "react"; +import type { SkeletonProps } from "@mui/material"; +import type { UseQueryResult } from "@tanstack/react-query"; +import type { FC, ReactNode } from "react"; +import { Skeleton } from "@mui/material"; import { isResponseNot200Error } from "../util/fetch"; interface LoadingSkeletonProps extends SkeletonProps { @@ -14,11 +15,12 @@ export const LoadingSkeleton: FC = ({ ...props }) => { const isError = queries.some(query => query.isError); - if (isError) + if (isError) { throw ( - queries.find(query => isResponseNot200Error(query.error))?.error ?? - new Error("Error fetching data, unable to reach the server") + queries.find(query => isResponseNot200Error(query.error))?.error + ?? new Error("Error fetching data, unable to reach the server") ); + } const isLoading = queries.some(query => query.isLoading); diff --git a/vinvoor/src/components/ProtectedRoute.tsx b/vinvoor/src/components/ProtectedRoute.tsx index 5400de4..8783e63 100644 --- a/vinvoor/src/components/ProtectedRoute.tsx +++ b/vinvoor/src/components/ProtectedRoute.tsx @@ -1,4 +1,4 @@ -import { FC, ReactNode } from "react"; +import type { FC, ReactNode } from "react"; import { Navigate } from "react-router-dom"; import { useUser } from "../hooks/useUser"; @@ -9,7 +9,8 @@ interface ProtectedRouteProps { export const ProtectedRoute: FC = ({ children }) => { const { data: user } = useUser(); - if (!user?.admin) return ; + if (!user?.admin) + return ; return children; }; diff --git a/vinvoor/src/components/TypographyG.tsx b/vinvoor/src/components/TypographyG.tsx index 8d166f7..e223b57 100644 --- a/vinvoor/src/components/TypographyG.tsx +++ b/vinvoor/src/components/TypographyG.tsx @@ -1,6 +1,7 @@ -import { Typography, TypographyProps } from "@mui/material"; -import { FC } from "react"; +import type { TypographyProps } from "@mui/material"; +import type { FC } from "react"; +import { Typography } from "@mui/material"; -export const TypographyG: FC = props => { +export const TypographyG: FC = (props) => { return ; }; diff --git a/vinvoor/src/components/UnstyledLink.tsx b/vinvoor/src/components/UnstyledLink.tsx index 7891e70..a42a3f1 100644 --- a/vinvoor/src/components/UnstyledLink.tsx +++ b/vinvoor/src/components/UnstyledLink.tsx @@ -1,7 +1,8 @@ -import { FC } from "react"; -import { Link, LinkProps } from "react-router-dom"; +import type { FC } from "react"; +import type { LinkProps } from "react-router-dom"; +import { Link } from "react-router-dom"; -export const UnstyledLink: FC = props => { +export const UnstyledLink: FC = (props) => { return ( ); diff --git a/vinvoor/src/errors/ErrorPage.tsx b/vinvoor/src/errors/ErrorPage.tsx index 29fd06d..2c5c941 100644 --- a/vinvoor/src/errors/ErrorPage.tsx +++ b/vinvoor/src/errors/ErrorPage.tsx @@ -2,20 +2,23 @@ import { Box, Typography } from "@mui/material"; import { isRouteErrorResponse, useRouteError } from "react-router-dom"; import CursesSob from "/cursed_sob.png"; -const get_error = (error: unknown) => { +function get_error(error: unknown) { if (isRouteErrorResponse(error)) { return `${error.status} ${error.statusText}`; - } else if (error instanceof Error) { + } + else if (error instanceof Error) { return error.message; - } else if (typeof error === "string") { + } + else if (typeof error === "string") { return error; - } else { + } + else { console.error(error); return "Unknown error"; } -}; +} -export const ErrorPage = () => { +export function ErrorPage() { const error = useRouteError(); return ( @@ -42,4 +45,4 @@ export const ErrorPage = () => { ); -}; +} diff --git a/vinvoor/src/footer/Footer.tsx b/vinvoor/src/footer/Footer.tsx index 3336c34..17090ab 100644 --- a/vinvoor/src/footer/Footer.tsx +++ b/vinvoor/src/footer/Footer.tsx @@ -3,7 +3,7 @@ import { TypographyG } from "../components/TypographyG"; import { useVersion } from "../hooks/useVersion"; import ZeusIcon from "/zeus.svg"; -export const Footer = () => { +export function Footer() { const { data: version } = useVersion(); return ( @@ -14,7 +14,10 @@ export const Footer = () => { alignItems: "center", }} > - v {version?.version ?? ""} + + v + {version?.version ?? ""} + { ); -}; +} diff --git a/vinvoor/src/hooks/admin/useAdminDays.ts b/vinvoor/src/hooks/admin/useAdminDays.ts index 2f0afa7..931df69 100644 --- a/vinvoor/src/hooks/admin/useAdminDays.ts +++ b/vinvoor/src/hooks/admin/useAdminDays.ts @@ -1,27 +1,31 @@ +import type { Dayjs } from "dayjs"; +import type { Day, DayJSON } from "../../types/days"; import { useMutation, useQuery } from "@tanstack/react-query"; -import { convertDayJSON, Day, DayJSON } from "../../types/days"; +import { convertDayJSON } from "../../types/days"; import { deleteAPI, getApi, postApi } from "../../util/fetch"; -import { Dayjs } from "dayjs"; const ENDPOINT = "admin/days"; -export const useAdminDays = () => - useQuery({ +export function useAdminDays() { + return useQuery({ queryKey: ["adminDays"], - queryFn: () => getApi(ENDPOINT, convertDayJSON), + queryFn: async () => getApi(ENDPOINT, convertDayJSON), retry: 1, }); +} -export const useAdminAddDay = () => - useMutation({ - mutationFn: (args: { startDate: Dayjs; endDate: Dayjs }) => +export function useAdminAddDay() { + return useMutation({ + mutationFn: async (args: { startDate: Dayjs; endDate: Dayjs }) => postApi(ENDPOINT, { start_date: args.startDate.format("YYYY-MM-DD"), end_date: args.endDate.format("YYYY-MM-DD"), }), }); +} -export const useAdminDeleteDay = () => - useMutation({ - mutationFn: (id: number) => deleteAPI(`${ENDPOINT}/${id}`), +export function useAdminDeleteDay() { + return useMutation({ + mutationFn: async (id: number) => deleteAPI(`${ENDPOINT}/${id}`), }); +} diff --git a/vinvoor/src/hooks/admin/useAdminSeason.ts b/vinvoor/src/hooks/admin/useAdminSeason.ts index bc6fbab..0231aed 100644 --- a/vinvoor/src/hooks/admin/useAdminSeason.ts +++ b/vinvoor/src/hooks/admin/useAdminSeason.ts @@ -1,29 +1,32 @@ +import type { Dayjs } from "dayjs"; +import type { Season, SeasonJSON } from "../../types/seasons"; import { useMutation, useQuery } from "@tanstack/react-query"; +import { convertSeasonJSON } from "../../types/seasons"; import { deleteAPI, getApi, postApi } from "../../util/fetch"; -import { Dayjs } from "dayjs"; -import { convertSeasonJSON, Season, SeasonJSON } from "../../types/seasons"; const ENDPOINT = "admin/seasons"; -export const useAdminSeasons = () => { +export function useAdminSeasons() { return useQuery({ queryKey: ["adminSeasons"], - queryFn: () => getApi(ENDPOINT, convertSeasonJSON), + queryFn: async () => getApi(ENDPOINT, convertSeasonJSON), retry: 1, }); -}; +} -export const useAdminAddSeason = () => - useMutation({ - mutationFn: (args: { name: string; startDate: Dayjs; endDate: Dayjs }) => +export function useAdminAddSeason() { + return useMutation({ + mutationFn: async (args: { name: string; startDate: Dayjs; endDate: Dayjs }) => postApi(ENDPOINT, { name: args.name, start: args.startDate.format("YYYY-MM-DD"), end: args.endDate.format("YYYY-MM-DD"), }), }); +} -export const useAdminDeleteSeason = () => - useMutation({ - mutationFn: (id: number) => deleteAPI(`${ENDPOINT}/${id}`), +export function useAdminDeleteSeason() { + return useMutation({ + mutationFn: async (id: number) => deleteAPI(`${ENDPOINT}/${id}`), }); +} diff --git a/vinvoor/src/hooks/useCard.ts b/vinvoor/src/hooks/useCard.ts index d9e0574..a098f2a 100644 --- a/vinvoor/src/hooks/useCard.ts +++ b/vinvoor/src/hooks/useCard.ts @@ -1,21 +1,23 @@ +import type { Card, CardJSON } from "../types/cards"; import { useMutation, useQuery } from "@tanstack/react-query"; -import { Card, CardJSON, convertCardJSON } from "../types/cards"; +import { convertCardJSON } from "../types/cards"; import { getApi, patchApi } from "../util/fetch"; const ENDPOINT = "cards"; -export const useCards = () => - useQuery({ +export function useCards() { + return useQuery({ queryKey: ["cards"], - queryFn: () => getApi(ENDPOINT, convertCardJSON), + queryFn: async () => getApi(ENDPOINT, convertCardJSON), retry: 1, }); +} -export const usePatchCards = () => { +export function usePatchCards() { return useMutation({ - mutationFn: (args: { id: number; newName: string }) => + mutationFn: async (args: { id: number; newName: string }) => patchApi(`${ENDPOINT}/${args.id}`, { name: args.newName, }), }); -}; +} diff --git a/vinvoor/src/hooks/useLeaderboard.ts b/vinvoor/src/hooks/useLeaderboard.ts index 5301b0f..a1cb9f8 100644 --- a/vinvoor/src/hooks/useLeaderboard.ts +++ b/vinvoor/src/hooks/useLeaderboard.ts @@ -1,20 +1,23 @@ +import type { + LeaderboardItem, + LeaderboardItemJSON, +} from "../types/leaderboard"; import { useQuery } from "@tanstack/react-query"; -import { getApi } from "../util/fetch"; import { convertLeaderboardItemJSON, - LeaderboardItem, - LeaderboardItemJSON, } from "../types/leaderboard"; +import { getApi } from "../util/fetch"; const ENDPOINT = "leaderboard"; -export const useLeaderboardItems = () => - useQuery({ +export function useLeaderboardItems() { + return useQuery({ queryKey: ["leaderboard"], - queryFn: () => + queryFn: async () => getApi( ENDPOINT, convertLeaderboardItemJSON, ), retry: 1, }); +} diff --git a/vinvoor/src/hooks/useScan.ts b/vinvoor/src/hooks/useScan.ts index 24ca8b7..4f18f55 100644 --- a/vinvoor/src/hooks/useScan.ts +++ b/vinvoor/src/hooks/useScan.ts @@ -1,12 +1,14 @@ +import type { Scan, ScanJSON } from "../types/scans"; import { useQuery } from "@tanstack/react-query"; +import { convertScanJSON } from "../types/scans"; import { getApi } from "../util/fetch"; -import { convertScanJSON, Scan, ScanJSON } from "../types/scans"; const ENDPOINT = "scans"; -export const useScans = () => - useQuery({ +export function useScans() { + return useQuery({ queryKey: ["scans"], - queryFn: () => getApi(ENDPOINT, convertScanJSON), + queryFn: async () => getApi(ENDPOINT, convertScanJSON), retry: 1, }); +} diff --git a/vinvoor/src/hooks/useSeasons.ts b/vinvoor/src/hooks/useSeasons.ts index f5221a7..e573f1b 100644 --- a/vinvoor/src/hooks/useSeasons.ts +++ b/vinvoor/src/hooks/useSeasons.ts @@ -1,19 +1,21 @@ -import { MutateOptions, useQuery } from "@tanstack/react-query"; +import type { MutateOptions } from "@tanstack/react-query"; +import type { Season, SeasonJSON } from "../types/seasons"; +import { useQuery } from "@tanstack/react-query"; +import { convertSeasonJSON } from "../types/seasons"; import { getApi } from "../util/fetch"; -import { convertSeasonJSON, Season, SeasonJSON } from "../types/seasons"; import { usePatchSettings } from "./useSettings"; const ENDPOINT = "seasons"; -export const useSeasons = () => { +export function useSeasons() { return useQuery({ queryKey: ["seasons"], - queryFn: () => getApi(ENDPOINT, convertSeasonJSON), + queryFn: async () => getApi(ENDPOINT, convertSeasonJSON), retry: 1, }); -}; +} -export const useSetSeason = () => { +export function useSetSeason() { const { mutate, ...other } = usePatchSettings(); const setSeason = ( @@ -27,4 +29,4 @@ export const useSetSeason = () => { ) => mutate({ season: id }, options); return { setSeason, ...other }; -}; +} diff --git a/vinvoor/src/hooks/useSettings.ts b/vinvoor/src/hooks/useSettings.ts index 3432b31..0346cef 100644 --- a/vinvoor/src/hooks/useSettings.ts +++ b/vinvoor/src/hooks/useSettings.ts @@ -1,25 +1,27 @@ +import type { Settings, SettingsJSON } from "../types/settings"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { converSettingsJSON } from "../types/settings"; import { getApi, patchApi } from "../util/fetch"; -import { converSettingsJSON, Settings, SettingsJSON } from "../types/settings"; const ENDPOINT = "settings"; -export const useSettings = () => - useQuery({ +export function useSettings() { + return useQuery({ queryKey: ["settings"], - queryFn: () => getApi(ENDPOINT, converSettingsJSON), + queryFn: async () => getApi(ENDPOINT, converSettingsJSON), retry: 1, }); +} -export const usePatchSettings = () => { +export function usePatchSettings() { const queryClient = useQueryClient(); return useMutation({ - mutationFn: (args: Record) => + mutationFn: async (args: Record) => patchApi(ENDPOINT, args), - onSuccess: () => + onSuccess: async () => queryClient.invalidateQueries({ predicate: query => query.queryKey[0] !== "settings", }), }); -}; +} diff --git a/vinvoor/src/hooks/useUser.ts b/vinvoor/src/hooks/useUser.ts index db25b63..52ffaab 100644 --- a/vinvoor/src/hooks/useUser.ts +++ b/vinvoor/src/hooks/useUser.ts @@ -1,18 +1,20 @@ +import type { User, UserJSON } from "../types/user"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { convertUserJSON } from "../types/user"; import { getApi, isResponseNot200Error, postApi } from "../util/fetch"; -import { convertUserJSON, User, UserJSON } from "../types/user"; const ENDPOINT = "user"; -export const useUser = () => - useQuery({ +export function useUser() { + return useQuery({ queryKey: ["user"], queryFn: async () => { let user = {} as User; try { user = await getApi(ENDPOINT, convertUserJSON); - } catch (error) { + } + catch (error) { if (!isResponseNot200Error(error)) throw new Error("Failed to fetch user"); } @@ -21,15 +23,16 @@ export const useUser = () => }, retry: 1, }); +} -export const useLogout = () => { +export function useLogout() { const queryClient = useQueryClient(); return useMutation({ - mutationFn: () => postApi("logout"), - onSuccess: () => + mutationFn: async () => postApi("logout"), + onSuccess: async () => queryClient.invalidateQueries({ queryKey: ["user"], }), }); -}; +} diff --git a/vinvoor/src/hooks/useVersion.ts b/vinvoor/src/hooks/useVersion.ts index b1087ec..8deec45 100644 --- a/vinvoor/src/hooks/useVersion.ts +++ b/vinvoor/src/hooks/useVersion.ts @@ -1,12 +1,14 @@ +import type { Version, VersionJSON } from "../types/version"; import { useQuery } from "@tanstack/react-query"; -import { convertVersionJSON, Version, VersionJSON } from "../types/version"; +import { convertVersionJSON } from "../types/version"; import { getApi } from "../util/fetch"; const ENDPOINT = "version"; -export const useVersion = () => - useQuery({ +export function useVersion() { + return useQuery({ queryKey: ["version"], - queryFn: () => getApi(ENDPOINT, convertVersionJSON), + queryFn: async () => getApi(ENDPOINT, convertVersionJSON), retry: 1, }); +} diff --git a/vinvoor/src/leaderboard/Leaderboard.tsx b/vinvoor/src/leaderboard/Leaderboard.tsx index e69385d..3f083ac 100644 --- a/vinvoor/src/leaderboard/Leaderboard.tsx +++ b/vinvoor/src/leaderboard/Leaderboard.tsx @@ -1,10 +1,10 @@ import { Divider, Paper, Table, TableContainer } from "@mui/material"; import { LoadingSkeleton } from "../components/LoadingSkeleton"; +import { useLeaderboardItems } from "../hooks/useLeaderboard"; import { LeaderboardTableBody } from "./LeaderboardTableBody"; import { LeaderboardTableToolbar } from "./LeaderboardTableToolbar"; -import { useLeaderboardItems } from "../hooks/useLeaderboard"; -export const Leaderboard = () => { +export function Leaderboard() { const leaderboardQuery = useLeaderboardItems(); return ( @@ -20,4 +20,4 @@ export const Leaderboard = () => { ); -}; +} diff --git a/vinvoor/src/leaderboard/LeaderboardTableBody.tsx b/vinvoor/src/leaderboard/LeaderboardTableBody.tsx index 2057208..eaaa2e7 100644 --- a/vinvoor/src/leaderboard/LeaderboardTableBody.tsx +++ b/vinvoor/src/leaderboard/LeaderboardTableBody.tsx @@ -1,3 +1,6 @@ +import type { Theme } from "@mui/material/styles"; +import type { TableHeadCell } from "../types/general"; +import type { LeaderboardItem } from "../types/leaderboard"; import { Icon, TableBody, @@ -5,11 +8,10 @@ import { TableRow, Typography, } from "@mui/material"; -import { alpha, Theme, useTheme } from "@mui/material/styles"; +import { alpha, useTheme } from "@mui/material/styles"; import { useLeaderboardItems } from "../hooks/useLeaderboard"; import { useUser } from "../hooks/useUser"; -import { TableHeadCell } from "../types/general"; -import { leaderboardHeadCells, LeaderboardItem } from "../types/leaderboard"; +import { leaderboardHeadCells } from "../types/leaderboard"; import FirstPlaceIcon from "/first_place.svg"; import SecondPlaceIcon from "/second_place.svg"; import ThirdPlaceIcon from "/third_place.svg"; @@ -26,21 +28,23 @@ const leaderboardText = [ { fontSize: "18px", fontWeight: "bold" }, ]; -const getLeaderboardColor = (index: number, theme: Theme) => - leaderboardColors[index] +function getLeaderboardColor(index: number, theme: Theme) { + return leaderboardColors[index] ? { backgroundColor: leaderboardColors[index](theme) } : {}; +} const getLeaderboardText = (index: number) => leaderboardText[index] || {}; -const getPositionChange = (positionChange: number) => { +function getPositionChange(positionChange: number) { let color = "text.primary"; let prefix = ""; if (positionChange > 0) { color = "success.light"; prefix = "+"; - } else if (positionChange < 0) { + } + else if (positionChange < 0) { color = "error.light"; } @@ -50,9 +54,9 @@ const getPositionChange = (positionChange: number) => { {positionChange !== 0 && positionChange} ); -}; +} -const getPosition = (position: number) => { +function getPosition(position: number) { switch (position) { case 1: return ( @@ -75,12 +79,9 @@ const getPosition = (position: number) => { default: return {position}; } -}; +} -const getCell = ( - row: LeaderboardItem, - headCell: TableHeadCell, -) => { +function getCell(row: LeaderboardItem, headCell: TableHeadCell) { switch (headCell.id) { case "positionChange": return getPositionChange(row[headCell.id]); @@ -97,15 +98,16 @@ const getCell = ( ); } -}; +} -export const LeaderboardTableBody = () => { +export function LeaderboardTableBody() { const { data: rows } = useLeaderboardItems(); - if (!rows) return null; // Can never happen - const theme = useTheme(); const { data: user } = useUser(); + if (!rows) + return null; // Can never happen + return ( {rows.map((row, index) => { @@ -141,4 +143,4 @@ export const LeaderboardTableBody = () => { })} ); -}; +} diff --git a/vinvoor/src/leaderboard/LeaderboardTableToolbar.tsx b/vinvoor/src/leaderboard/LeaderboardTableToolbar.tsx index 2987440..5db2e9b 100644 --- a/vinvoor/src/leaderboard/LeaderboardTableToolbar.tsx +++ b/vinvoor/src/leaderboard/LeaderboardTableToolbar.tsx @@ -3,7 +3,7 @@ import { Button, Toolbar, Typography } from "@mui/material"; import { HashLink } from "react-router-hash-link"; import { useUser } from "../hooks/useUser"; -export const LeaderboardTableToolbar = () => { +export function LeaderboardTableToolbar() { const { data: user } = useUser(); return ( @@ -19,4 +19,4 @@ export const LeaderboardTableToolbar = () => { ); -}; +} diff --git a/vinvoor/src/main.tsx b/vinvoor/src/main.tsx index ba5b187..359b98d 100644 --- a/vinvoor/src/main.tsx +++ b/vinvoor/src/main.tsx @@ -1,27 +1,27 @@ -import "@fontsource/roboto/300.css"; -import "@fontsource/roboto/400.css"; -import "@fontsource/roboto/500.css"; -import "@fontsource/roboto/700.css"; import { CssBaseline } from "@mui/material"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ConfirmProvider } from "material-ui-confirm"; import React from "react"; import ReactDOM from "react-dom/client"; import { createBrowserRouter, RouterProvider } from "react-router-dom"; -import "react-tooltip/dist/react-tooltip.css"; import { App } from "./App.tsx"; +import { Login } from "./auth/Login.tsx"; +import { Logout } from "./auth/Logout.tsx"; import { Cards } from "./cards/Cards.tsx"; import { ProtectedRoute } from "./components/ProtectedRoute.tsx"; import { ErrorPage } from "./errors/ErrorPage.tsx"; import { Leaderboard } from "./leaderboard/Leaderboard.tsx"; +import { NavBar } from "./navbar/NavBar.tsx"; import { CustomSnackbarProvider } from "./providers/CustomSnackbarProvider.tsx"; import { ThemeProvider } from "./providers/ThemeProvider.tsx"; import { Scans } from "./scans/Scans.tsx"; import { Admin } from "./settings/admin/Admin.tsx"; import { SettingsOverview } from "./settings/SettingsOverview.tsx"; -import { Login } from "./auth/Login.tsx"; -import { Logout } from "./auth/Logout.tsx"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { NavBar } from "./navbar/NavBar.tsx"; +import "@fontsource/roboto/300.css"; +import "@fontsource/roboto/400.css"; +import "@fontsource/roboto/500.css"; +import "@fontsource/roboto/700.css"; +import "react-tooltip/dist/react-tooltip.css"; const queryClient = new QueryClient(); diff --git a/vinvoor/src/navbar/NavBar.tsx b/vinvoor/src/navbar/NavBar.tsx index 176382f..7d8ca7a 100644 --- a/vinvoor/src/navbar/NavBar.tsx +++ b/vinvoor/src/navbar/NavBar.tsx @@ -30,7 +30,7 @@ const userMenuPages: PageIcon[] = [ { page: "Settings", icon: }, ]; -export const NavBar = () => { +export function NavBar() { const { data: user } = useUser(); const [selectedPage, setSelectedPage] = useState(""); const showSeasons = useMediaQuery("(min-width:400px)"); @@ -110,4 +110,4 @@ export const NavBar = () => { ); -}; +} diff --git a/vinvoor/src/navbar/NavBarLogo.tsx b/vinvoor/src/navbar/NavBarLogo.tsx index 7b953fe..c59aed2 100644 --- a/vinvoor/src/navbar/NavBarLogo.tsx +++ b/vinvoor/src/navbar/NavBarLogo.tsx @@ -1,6 +1,8 @@ -import { Box, Button, SxProps, Theme, Typography } from "@mui/material"; +import type { SxProps, Theme } from "@mui/material"; +import type { FC } from "react"; +import { Box, Button, Typography } from "@mui/material"; import { HexagonSlice6 } from "mdi-material-ui"; -import { FC, useContext } from "react"; +import { useContext } from "react"; import { UnstyledLink } from "../components/UnstyledLink"; import { ThemeContext } from "../providers/ThemeProvider"; @@ -23,18 +25,21 @@ export const NavBarLogo: FC = ({ }) => { const { setTheme } = useContext(ThemeContext); const handleClick = () => { - if (handleSelectedPage) handleSelectedPage("home"); + if (handleSelectedPage) + handleSelectedPage("home"); if (pressedAmount < CLICK_AMOUNT) { - if (pressedAmount === 0) startTimePress = Date.now(); + if (pressedAmount === 0) + startTimePress = Date.now(); pressedAmount++; if ( - pressedAmount === CLICK_AMOUNT && - Date.now() - startTimePress <= CLICK_TIME_MS - ) + pressedAmount === CLICK_AMOUNT + && Date.now() - startTimePress <= CLICK_TIME_MS + ) { setTheme("kak"); + } } }; diff --git a/vinvoor/src/navbar/NavBarPages.tsx b/vinvoor/src/navbar/NavBarPages.tsx index 1d626c1..fb4c660 100644 --- a/vinvoor/src/navbar/NavBarPages.tsx +++ b/vinvoor/src/navbar/NavBarPages.tsx @@ -1,7 +1,8 @@ -import { Box, Button, SxProps, Theme, Typography } from "@mui/material"; -import { FC } from "react"; +import type { SxProps, Theme } from "@mui/material"; +import type { FC } from "react"; +import type { PageIcon } from "./NavBar"; +import { Box, Button, Typography } from "@mui/material"; import { UnstyledLink } from "../components/UnstyledLink"; -import { PageIcon } from "./NavBar"; interface NavBarPagesProps { pageIcons: readonly PageIcon[]; diff --git a/vinvoor/src/navbar/NavBarSandwich.tsx b/vinvoor/src/navbar/NavBarSandwich.tsx index 2c6b18f..ba9571c 100644 --- a/vinvoor/src/navbar/NavBarSandwich.tsx +++ b/vinvoor/src/navbar/NavBarSandwich.tsx @@ -1,16 +1,19 @@ +import type { + SxProps, + Theme, +} from "@mui/material"; +import type { FC, MouseEvent } from "react"; +import type { PageIcon } from "./NavBar"; import MenuIcon from "@mui/icons-material/Menu"; import { Box, IconButton, Menu, MenuItem, - SxProps, - Theme, Typography, } from "@mui/material"; -import { FC, MouseEvent, useState } from "react"; +import { useState } from "react"; import { UnstyledLink } from "../components/UnstyledLink"; -import { PageIcon } from "./NavBar"; interface NavBarSandwichProps { pageIcons: readonly PageIcon[]; diff --git a/vinvoor/src/navbar/NavBarSeasons.tsx b/vinvoor/src/navbar/NavBarSeasons.tsx index 85c776b..bb096ed 100644 --- a/vinvoor/src/navbar/NavBarSeasons.tsx +++ b/vinvoor/src/navbar/NavBarSeasons.tsx @@ -1,10 +1,11 @@ -import { useState, MouseEvent } from "react"; +import type { MouseEvent } from "react"; +import { ArrowDropDown, Refresh } from "@mui/icons-material"; +import { Button, IconButton, Menu, MenuItem, Typography } from "@mui/material"; +import { useState } from "react"; import { useSeasons, useSetSeason } from "../hooks/useSeasons"; import { useSettings } from "../hooks/useSettings"; -import { Button, IconButton, Menu, MenuItem, Typography } from "@mui/material"; -import { ArrowDropDown, Refresh } from "@mui/icons-material"; -export const NavBarSeasons = () => { +export function NavBarSeasons() { const { data: seasons } = useSeasons(); const { data: settings, refetch } = useSettings(); const { setSeason } = useSetSeason(); @@ -89,4 +90,4 @@ export const NavBarSeasons = () => { )} ); -}; +} diff --git a/vinvoor/src/navbar/NavBarUserMenu.tsx b/vinvoor/src/navbar/NavBarUserMenu.tsx index 78c493c..6ffc464 100644 --- a/vinvoor/src/navbar/NavBarUserMenu.tsx +++ b/vinvoor/src/navbar/NavBarUserMenu.tsx @@ -1,3 +1,5 @@ +import type { FC, MouseEvent } from "react"; +import type { PageIcon } from "./NavBar"; import { Button, Divider, @@ -8,13 +10,12 @@ import { } from "@mui/material"; import { useTheme } from "@mui/material/styles"; import { Cow, ExitRun, ShieldAccountOutline } from "mdi-material-ui"; -import { FC, MouseEvent, useState } from "react"; +import { useState } from "react"; import { Login } from "../auth/Login"; import { Logout } from "../auth/Logout"; import { BrowserView } from "../components/BrowserView"; import { UnstyledLink } from "../components/UnstyledLink"; import { useUser } from "../hooks/useUser"; -import { PageIcon } from "./NavBar"; interface NavBarUserMenuProps { pageIcons: readonly PageIcon[]; @@ -44,105 +45,109 @@ export const NavBarUserMenu: FC = ({ return ( <> - {user ? ( - <> - - - {pageIcons.map(({ page, icon }) => ( - - { - handleCloseUserMenu(); - if (isBrowserView) handleSelectedPage("user"); - }} - > - {icon} - {page} - - - ))} - - {user.admin && ( - + {user + ? ( + <> + + + {pageIcons.map(({ page, icon }) => ( + + { + handleCloseUserMenu(); + if (isBrowserView) + handleSelectedPage("user"); + }} + > + {icon} + {page} + + + ))} + + {user.admin && ( + + { + handleCloseUserMenu(); + if (isBrowserView) + handleSelectedPage("user"); + }} + sx={{ + "paddingX": "0", + "justifyContent": "center", + "backgroundColor": "error.dark", + "&:hover": { + backgroundColor: "error.light", + }, + }} + > + + Admin + + + )} { - handleCloseUserMenu(); - if (isBrowserView) handleSelectedPage("user"); - }} + onClick={handleCloseUserMenu} sx={{ paddingX: "0", justifyContent: "center", - backgroundColor: "error.dark", - "&:hover": { - backgroundColor: "error.light", - }, }} > - - Admin + + + {/* Hacky way to center it with the other icons */} + Logout + - - )} - - - - {/* Hacky way to center it with the other icons */} - Logout - - - - - ) : ( - - Login - - )} + + + ) + : ( + + Login + + )} ); }; diff --git a/vinvoor/src/overview/Overview.tsx b/vinvoor/src/overview/Overview.tsx index ce60813..c3b0e5f 100644 --- a/vinvoor/src/overview/Overview.tsx +++ b/vinvoor/src/overview/Overview.tsx @@ -4,16 +4,16 @@ import { useEffect, useLayoutEffect, useRef, useState } from "react"; import { Tooltip } from "react-tooltip"; import { BrowserView } from "../components/BrowserView"; import { LoadingSkeleton } from "../components/LoadingSkeleton"; +import { useScans } from "../hooks/useScan"; +import { useSeasons } from "../hooks/useSeasons"; +import { useSettings } from "../hooks/useSettings"; import { CheckIn } from "./checkin/CheckIn"; import { Days } from "./days/Days"; import { Heatmap } from "./heatmap/Heatmap"; import { HeatmapVariant } from "./heatmap/types"; import { Streak } from "./streak/Streak"; -import { useScans } from "../hooks/useScan"; -import { useSeasons } from "../hooks/useSeasons"; -import { useSettings } from "../hooks/useSettings"; -export const Overview = () => { +export function Overview() { const scansQuery = useScans(); const seasonsQuery = useSeasons(); const settingsQuery = useSettings(); @@ -47,7 +47,8 @@ export const Overview = () => { seasons.length > 1 ? seasons[1].start : seasons[0].start, new Date(), ]); - } else { + } + else { setHeatmapDates([currentSeason.start, currentSeason.end]); } } @@ -55,71 +56,73 @@ export const Overview = () => { return ( - {scansQuery.data?.length ? ( - - - - - - - - - - - setChecked(false)}> - - Months - - Days + {scansQuery.data?.length + ? ( + + + + + + + + + + + setChecked(false)}> + + Months + + Days + + + + - - - - - - - - - + + + + + + + + + ) + : ( + + + + You don't have any scans. + + + Start scanning to see some data! + + - - - ) : ( - - - - You don't have any scans. - - - Start scanning to see some data! - - - - )} + )} ); -}; +} diff --git a/vinvoor/src/overview/checkin/CheckIn.tsx b/vinvoor/src/overview/checkin/CheckIn.tsx index 83bc60b..bf3578d 100644 --- a/vinvoor/src/overview/checkin/CheckIn.tsx +++ b/vinvoor/src/overview/checkin/CheckIn.tsx @@ -1,31 +1,34 @@ import { Alert, AlertTitle } from "@mui/material"; import { EmoticonExcitedOutline, EmoticonFrownOutline } from "mdi-material-ui"; -import { isTheSameDay } from "../../util/util"; import { useScans } from "../../hooks/useScan"; +import { isTheSameDay } from "../../util/util"; -export const CheckIn = () => { +export function CheckIn() { const { data: scans } = useScans(); - if (!scans) return null; // Can never happen + if (!scans) + return null; // Can never happen const checkedIn = isTheSameDay(scans[scans.length - 1].scanTime, new Date()); - return checkedIn ? ( - } - > - Checked in - Nice of you to stop by ! - - ) : ( - } - > - Not checked in - We miss you ! - - ); -}; + return checkedIn + ? ( + } + > + Checked in + Nice of you to stop by ! + + ) + : ( + } + > + Not checked in + We miss you ! + + ); +} diff --git a/vinvoor/src/overview/days/Days.tsx b/vinvoor/src/overview/days/Days.tsx index 4167946..43bb6a1 100644 --- a/vinvoor/src/overview/days/Days.tsx +++ b/vinvoor/src/overview/days/Days.tsx @@ -1,21 +1,22 @@ +import type { ApexOptions } from "apexcharts"; +import type { Scan } from "../../types/scans"; import { useTheme } from "@mui/material"; -import { ApexOptions } from "apexcharts"; import Chart from "react-apexcharts"; -import { Scan } from "../../types/scans"; import { useScans } from "../../hooks/useScan"; -const getDayCount = (scans: readonly Scan[]) => { +function getDayCount(scans: readonly Scan[]) { const days = [0, 0, 0, 0, 0, 0, 0]; - scans.forEach(scan => { + scans.forEach((scan) => { days[scan.scanTime.getDay() - 1]++; }); return days.slice(0, -2) as ApexNonAxisChartSeries; -}; +} -export const Days = () => { +export function Days() { const theme = useTheme(); const { data: scans } = useScans(); - if (!scans) return null; // Can never happen + if (!scans) + return null; // Can never happen const state = { options: { @@ -65,4 +66,4 @@ export const Days = () => { return ( ); -}; +} diff --git a/vinvoor/src/overview/heatmap/Day.tsx b/vinvoor/src/overview/heatmap/Day.tsx index 4732712..df596e6 100644 --- a/vinvoor/src/overview/heatmap/Day.tsx +++ b/vinvoor/src/overview/heatmap/Day.tsx @@ -1,8 +1,9 @@ +import type { FC } from "react"; +import type { DayData, HeatmapVariant } from "./types"; import { useTheme } from "@mui/material"; -import { FC, useMemo } from "react"; -import "./heatmap.css"; +import { useMemo } from "react"; +import { useScans } from "../../hooks/useScan"; import { Rect } from "./Rect"; -import { DayData, HeatmapVariant } from "./types"; import { DATE_FORMATTER, DAYS_IN_WEEK, @@ -14,7 +15,7 @@ import { styleMonth, WEEKS_IN_MONTH, } from "./utils"; -import { useScans } from "../../hooks/useScan"; +import "./heatmap.css"; interface DayProps { startDate: Date; @@ -35,17 +36,16 @@ export const Day: FC = ({ }) => { const theme = useTheme(); const { data: scans } = useScans(); - if (!scans) return null; // Can never happen const data = useMemo(() => { - const normalizedScans = [...scans]; + const normalizedScans = [...scans ?? []]; // normalizedScans.forEach(scan => scan.scanTime.setHours(0, 0, 0, 0)); const formattedScans = formatData(normalizedScans); const start = new Date( - startDate.getTime() - - startDate.getDay() * MILLISECONDS_IN_DAY + - MILLISECONDS_IN_DAY, + startDate.getTime() + - startDate.getDay() * MILLISECONDS_IN_DAY + + MILLISECONDS_IN_DAY, ); const startDates = Array.from( @@ -58,7 +58,8 @@ export const Day: FC = ({ while (newStartDate.getDay() !== 1) { newStartDate.setDate(newStartDate.getDate() - 1); } - } else { + } + else { newStartDate.setMonth(newStartDate.getMonth() + idx); newStartDate.setDate(1); while (newStartDate.getDay() !== 1) { @@ -71,9 +72,9 @@ export const Day: FC = ({ ); const endWeek = new Date( - endDate.getTime() + - MILLISECONDS_IN_DAY * - (DAYS_IN_WEEK - (getMondayIndexedDay(endDate) % DAYS_IN_WEEK)), + endDate.getTime() + + MILLISECONDS_IN_DAY + * (DAYS_IN_WEEK - (getMondayIndexedDay(endDate) % DAYS_IN_WEEK)), ); return { @@ -84,6 +85,9 @@ export const Day: FC = ({ }; }, [scans, startDate, endDate]); + if (!scans) + return null; // Can never happen + return ( {Array.from({ length: columnCount }, (_, idx) => { @@ -91,79 +95,82 @@ export const Day: FC = ({ {isDayVariant(variant) ? Array.from({ length: DAYS_IN_WEEK }, (_, cidx) => { - const currentDate = new Date( - data.start.getTime() + - MILLISECONDS_IN_DAY * (idx * DAYS_IN_WEEK + cidx), - ); - - if (currentDate.getTime() < startDate.getTime()) return null; - - if (currentDate.getTime() > endDate.getTime()) return null; - - let colors = theme.heatmap.colorInActive; - if (data.data[currentDate.getTime()]) - colors = theme.heatmap.colorActive; - - const dataTooltipContent = `${ - data.data[currentDate.getTime()] ? "Present" : "Absent" - } on ${DATE_FORMATTER.format(currentDate)}`; - - return ( - - ); - }) + const currentDate = new Date( + data.start.getTime() + + MILLISECONDS_IN_DAY * (idx * DAYS_IN_WEEK + cidx), + ); + + if (currentDate.getTime() < startDate.getTime()) + return null; + + if (currentDate.getTime() > endDate.getTime()) + return null; + + let colors = theme.heatmap.colorInActive; + if (data.data[currentDate.getTime()]) + colors = theme.heatmap.colorActive; + + const dataTooltipContent = `${ + data.data[currentDate.getTime()] ? "Present" : "Absent" + } on ${DATE_FORMATTER.format(currentDate)}`; + + return ( + + ); + }) : Array.from({ length: WEEKS_IN_MONTH }, (_, cidx) => { - const currentDate = new Date( - data.startDates[idx].getTime() + - MILLISECONDS_IN_DAY * cidx * DAYS_IN_WEEK, - ); - - // Week is no longer in the month - if ( - currentDate.getMonth() > startDate.getMonth() + idx && - getMondayIndexedDay(currentDate) <= - currentDate.getDate() - 1 - ) - return null; - - // Week is after end date - if (currentDate.getTime() >= data.endWeek.getTime()) - return null; - - const count = Array.from( - { length: DAYS_IN_WEEK }, - (_, i) => - new Date(currentDate.getTime() + i * MILLISECONDS_IN_DAY), - ).filter( - date => - date.getTime() <= endDate.getTime() && - data.data[date.getTime()], - ).length; - - const colors = styleMonth[Math.min(count, 5)](theme); // Can be higher than 5 if multiple scans in a day or scanned during the weekend - - const dataTooltipContent = `${count} scan${ - count !== 1 ? "s" : "" - } in the week of ${DATE_FORMATTER.format(currentDate)}`; - - return ( - - ); - })} + const currentDate = new Date( + data.startDates[idx].getTime() + + MILLISECONDS_IN_DAY * cidx * DAYS_IN_WEEK, + ); + + // Week is no longer in the month + if ( + currentDate.getMonth() > startDate.getMonth() + idx + && getMondayIndexedDay(currentDate) + <= currentDate.getDate() - 1 + ) { + return null; + } + + // Week is after end date + if (currentDate.getTime() >= data.endWeek.getTime()) + return null; + + const count = Array.from( + { length: DAYS_IN_WEEK }, + (_, i) => + new Date(currentDate.getTime() + i * MILLISECONDS_IN_DAY), + ).filter( + date => + date.getTime() <= endDate.getTime() + && data.data[date.getTime()], + ).length; + + const colors = styleMonth[Math.min(count, 5)](theme); // Can be higher than 5 if multiple scans in a day or scanned during the weekend + + const dataTooltipContent = `${count} scan${ + count !== 1 ? "s" : "" + } in the week of ${DATE_FORMATTER.format(currentDate)}`; + + return ( + + ); + })} ); })} diff --git a/vinvoor/src/overview/heatmap/Heatmap.tsx b/vinvoor/src/overview/heatmap/Heatmap.tsx index fe1ae27..351805d 100644 --- a/vinvoor/src/overview/heatmap/Heatmap.tsx +++ b/vinvoor/src/overview/heatmap/Heatmap.tsx @@ -1,8 +1,8 @@ +import type { FC } from "react"; +import type { HeatmapVariant } from "./types"; import { useMediaQuery, useTheme } from "@mui/material"; -import { FC } from "react"; import { Day } from "./Day"; import { LabelsMonth } from "./LabelsMonth"; -import { HeatmapVariant } from "./types"; import { DAYS_IN_WEEK, getColumnCountDays, @@ -35,12 +35,12 @@ export const Heatmap: FC = ({ startDate, endDate, variant }) => { return ( = ({ {(isDayVariant(variant) ? data.day : data.month).map((item, idx) => { return ( { +// Consts + +export const DAYS_IN_WEEK = 7; +export const WEEKS_IN_MONTH = 5; +export const MILLISECONDS_IN_DAY = 1000 * 60 * 60 * 24; + +export function getColumnCountDays(startDate: Date, endDate: Date) { const startOfWeek = new Date(startDate); startOfWeek.setDate(startOfWeek.getDate() - startOfWeek.getDay()); @@ -12,43 +19,44 @@ export const getColumnCountDays = (startDate: Date, endDate: Date) => { else endOfWeek.setDate(endOfWeek.getDate() - endOfWeek.getDay() + 6); return Math.ceil( - (endOfWeek.getTime() - startOfWeek.getTime()) / - (DAYS_IN_WEEK * MILLISECONDS_IN_DAY), + (endOfWeek.getTime() - startOfWeek.getTime()) + / (DAYS_IN_WEEK * MILLISECONDS_IN_DAY), ); -}; +} -export const getColumnCountMonths = (startDate: Date, endDate: Date) => { +export function getColumnCountMonths(startDate: Date, endDate: Date) { return ( - (endDate.getFullYear() - startDate.getFullYear()) * 12 + - endDate.getMonth() - - startDate.getMonth() + - 1 + (endDate.getFullYear() - startDate.getFullYear()) * 12 + + endDate.getMonth() + - startDate.getMonth() + + 1 ); -}; +} export const getMondayIndexedDay = (date: Date) => (date.getDay() + 6) % 7; -const getNormalizedTime = (date: Date) => { +function getNormalizedTime(date: Date) { const result = new Date(date); result.setHours(0, 0, 0, 0); return result; -}; +} -export const formatData = (scans: Scan[]) => { +export function formatData(scans: Scan[]) { const result: Record = {}; - scans.forEach(scan => { + scans.forEach((scan) => { const date = getNormalizedTime(scan.scanTime); result[date.getTime()] = { - date: date, + date, count: 1, }; }); return result; -}; +} -export const isDayVariant = (variant: HeatmapVariant) => - variant === HeatmapVariant.DAYS; +export function isDayVariant(variant: HeatmapVariant) { + return variant === HeatmapVariant.DAYS; +} export const styleMonth = [ (theme: Theme) => theme.heatmap.color0, @@ -96,9 +104,3 @@ export const DATE_FORMATTER = new Intl.DateTimeFormat("en-GB", { month: "short", day: "numeric", }); - -// Consts - -export const DAYS_IN_WEEK = 7; -export const WEEKS_IN_MONTH = 5; -export const MILLISECONDS_IN_DAY = 1000 * 60 * 60 * 24; diff --git a/vinvoor/src/overview/streak/Streak.tsx b/vinvoor/src/overview/streak/Streak.tsx index c92f36c..6e3fd31 100644 --- a/vinvoor/src/overview/streak/Streak.tsx +++ b/vinvoor/src/overview/streak/Streak.tsx @@ -1,34 +1,36 @@ +import type { Scan } from "../../types/scans"; import { Box, Typography } from "@mui/material"; -import { Scan } from "../../types/scans"; +import { useScans } from "../../hooks/useScan"; import { isTheSameDay, MILLISECONDS_IN_ONE_DAY, shiftDate, } from "../../util/util"; -import { useScans } from "../../hooks/useScan"; -const isWeekendBetween = (date1: Date, date2: Date) => { +function isWeekendBetween(date1: Date, date2: Date) { const diffDays = Math.floor( (date2.getTime() - date1.getTime()) / MILLISECONDS_IN_ONE_DAY, ); - if (diffDays > 2) return false; + if (diffDays > 2) + return false; return date1.getDay() === 5 && [1, 6, 7].includes(date2.getDay()); -}; +} -const isStreakDay = (date1: Date, date2: Date) => { - if (isTheSameDay(date1, shiftDate(date2, 1))) return true; +function isStreakDay(date1: Date, date2: Date) { + if (isTheSameDay(date1, shiftDate(date2, 1))) + return true; if (date1.getDay() === 5 && [1, 6, 7].includes(date2.getDay())) return isWeekendBetween(date1, date2); return false; -}; +} -const getStreak = (scans: readonly Scan[]): [boolean, number] => { +function getStreak(scans: readonly Scan[]): [boolean, number] { const dates = scans - .map(scan => { + .map((scan) => { const date = new Date(scan.scanTime); date.setHours(0, 0, 0, 0); return date; @@ -42,60 +44,67 @@ const getStreak = (scans: readonly Scan[]): [boolean, number] => { let streak = 0; - const isOnStreak = - isTheSameDay(dates[dates.length - 1], new Date()) || - isWeekendBetween(dates[dates.length - 1], new Date()); + const isOnStreak + = isTheSameDay(dates[dates.length - 1], new Date()) + || isWeekendBetween(dates[dates.length - 1], new Date()); if (isOnStreak) { let i = dates.length; streak++; while (i-- > 1 && isStreakDay(dates[i], dates[i - 1])) streak++; - } else { - streak = - dates.length > 0 + } + else { + streak + = dates.length > 0 ? Math.floor( - (new Date().getTime() - dates[dates.length - 1].getTime()) / - MILLISECONDS_IN_ONE_DAY - - 1, - ) + (new Date().getTime() - dates[dates.length - 1].getTime()) + / MILLISECONDS_IN_ONE_DAY + - 1, + ) : 0; } return [isOnStreak, streak]; -}; +} -export const Streak = () => { +export function Streak() { const { data: scans } = useScans(); - if (!scans) return null; // Can never happen + if (!scans) + return null; // Can never happen const [isOnStreak, streak] = getStreak(scans); const color = isOnStreak ? "primary" : "error"; const textEnd = isOnStreak ? "streak" : "absent"; - return streak === 0 ? ( - `1px solid ${theme.palette.primary.main}`} - borderBottom={theme => `1px solid ${theme.palette.primary.main}`} - > - - Scan to retain streak - - - ) : ( - - - {streak} - - - day{streak > 1 ? "s" : ""} {textEnd} - - - ); -}; + return streak === 0 + ? ( + `1px solid ${theme.palette.primary.main}`} + borderBottom={theme => `1px solid ${theme.palette.primary.main}`} + > + + Scan to retain streak + + + ) + : ( + + + {streak} + + + day + {streak > 1 ? "s" : ""} + {" "} + {textEnd} + + + ); +} diff --git a/vinvoor/src/providers/CustomSnackbarProvider.tsx b/vinvoor/src/providers/CustomSnackbarProvider.tsx index caf051d..58f37ba 100644 --- a/vinvoor/src/providers/CustomSnackbarProvider.tsx +++ b/vinvoor/src/providers/CustomSnackbarProvider.tsx @@ -1,10 +1,12 @@ +import type { + SnackbarProviderProps, +} from "notistack"; +import type { FC } from "react"; import { styled, useTheme } from "@mui/material/styles"; import { MaterialDesignContent, SnackbarProvider, - SnackbarProviderProps, } from "notistack"; -import { FC } from "react"; export const CustomSnackbarProvider: FC = ({ children, diff --git a/vinvoor/src/providers/ThemeProvider.tsx b/vinvoor/src/providers/ThemeProvider.tsx index 6608456..b253bfa 100644 --- a/vinvoor/src/providers/ThemeProvider.tsx +++ b/vinvoor/src/providers/ThemeProvider.tsx @@ -1,7 +1,12 @@ +import type { FC, ReactNode } from "react"; +import type { ThemeMode } from "../themes/theme"; import { ThemeProvider as MUIThemeProvider } from "@mui/material"; import Cookies from "js-cookie"; -import { createContext, FC, ReactNode, useEffect, useState } from "react"; -import { ThemeMode, themeModes } from "../themes/theme"; +import { createContext, useEffect, useState } from "react"; +import { themeModes } from "../themes/theme"; + +/* eslint-disable react-refresh/only-export-components, react/no-unstable-context-value */ +// TODO interface ThemeProviderProps { children: ReactNode; diff --git a/vinvoor/src/scans/Scans.tsx b/vinvoor/src/scans/Scans.tsx index 6d5812d..691d886 100644 --- a/vinvoor/src/scans/Scans.tsx +++ b/vinvoor/src/scans/Scans.tsx @@ -1,11 +1,11 @@ import { Paper, Table, TableContainer } from "@mui/material"; import { LoadingSkeleton } from "../components/LoadingSkeleton"; +import { useCards } from "../hooks/useCard"; +import { useScans } from "../hooks/useScan"; import { ScansTableBody } from "./ScansTableBody"; import { ScansTableHead } from "./ScansTableHead"; -import { useScans } from "../hooks/useScan"; -import { useCards } from "../hooks/useCard"; -export const Scans = () => { +export function Scans() { const scansQuery = useScans(); const cardsQuery = useCards(); @@ -21,4 +21,4 @@ export const Scans = () => { ); -}; +} diff --git a/vinvoor/src/scans/ScansTableBody.tsx b/vinvoor/src/scans/ScansTableBody.tsx index 03598b3..6e3e5ff 100644 --- a/vinvoor/src/scans/ScansTableBody.tsx +++ b/vinvoor/src/scans/ScansTableBody.tsx @@ -1,28 +1,31 @@ +import type { ScanCard } from "../types/scans"; import { TableBody, TableCell, TableRow, Typography } from "@mui/material"; import { useEffect, useState } from "react"; -import { mergeScansCards, ScanCard, scanCardHeadCells } from "../types/scans"; import { useCards } from "../hooks/useCard"; import { useScans } from "../hooks/useScan"; +import { mergeScansCards, scanCardHeadCells } from "../types/scans"; -export const ScansTableBody = () => { +export function ScansTableBody() { const { data: scans } = useScans(); const { data: cards } = useCards(); - if (!scans || !cards) return null; // Can never happen const [scanCards, setScanCards] = useState([]); useEffect(() => { - const mergedScansCards = mergeScansCards(scans, cards); + const mergedScansCards = mergeScansCards(scans ?? [], cards ?? []); mergedScansCards.sort( (a, b) => b.scanTime.getTime() - a.scanTime.getTime(), ); setScanCards(mergedScansCards); }, [scans, cards]); + if (!scans || !cards) + return null; // Can never happen + return ( - {scanCards.map((scanCard, index) => ( - + {scanCards.map(scanCard => ( + {scanCardHeadCells.map(headCell => ( { ))} ); -}; +} diff --git a/vinvoor/src/scans/ScansTableHead.tsx b/vinvoor/src/scans/ScansTableHead.tsx index 380ad01..227da60 100644 --- a/vinvoor/src/scans/ScansTableHead.tsx +++ b/vinvoor/src/scans/ScansTableHead.tsx @@ -1,7 +1,7 @@ import { TableCell, TableHead, TableRow, Typography } from "@mui/material"; import { scanCardHeadCells } from "../types/scans"; -export const ScansTableHead = () => { +export function ScansTableHead() { return ( @@ -13,4 +13,4 @@ export const ScansTableHead = () => { ); -}; +} diff --git a/vinvoor/src/settings/Settings.tsx b/vinvoor/src/settings/Settings.tsx index e43bd38..730ed22 100644 --- a/vinvoor/src/settings/Settings.tsx +++ b/vinvoor/src/settings/Settings.tsx @@ -5,7 +5,6 @@ import { MenuItem, Paper, Select, - SelectChangeEvent, Stack, Tooltip, Typography, @@ -30,20 +29,26 @@ const handleDeleteContent = ( ); -export const Settings = () => { +export function Settings() { const { data: settingsTruth, refetch } = useSettings(); const { data: seasons } = useSeasons(); - if (!settingsTruth || !seasons) return null; // Can never happen const patchSettings = usePatchSettings(); const [settings, setSettings] = useState({ ...settingsTruth }); const { enqueueSnackbar } = useSnackbar(); const confirm = useConfirm(); + useEffect(() => { + setSettings({ ...settingsTruth, season: settingsTruth?.season }); + }, [settingsTruth?.season]); + + if (!settingsTruth || !seasons) + return null; // Can never happen + const handleSeasonChange = (event: SelectChangeEvent) => setSettings({ ...settings, - season: parseInt(event.target.value), + season: Number.parseInt(event.target.value), }); const handleSubmit = () => { @@ -74,10 +79,6 @@ export const Settings = () => { }); }; - useEffect(() => { - setSettings({ ...settingsTruth, season: settingsTruth.season }); - }, [settingsTruth.season]); - return ( { value={ seasons .find(season => season.id === settings.season) - ?.id.toString() ?? seasons[0].id.toString() + ?.id + .toString() ?? seasons[0].id.toString() } onChange={handleSeasonChange} sx={{ ml: "20px" }} @@ -150,4 +152,4 @@ export const Settings = () => { ); -}; +} diff --git a/vinvoor/src/settings/SettingsOverview.tsx b/vinvoor/src/settings/SettingsOverview.tsx index dff72f3..1ea66ad 100644 --- a/vinvoor/src/settings/SettingsOverview.tsx +++ b/vinvoor/src/settings/SettingsOverview.tsx @@ -2,7 +2,7 @@ import { LoadingSkeleton } from "../components/LoadingSkeleton"; import { useSettings } from "../hooks/useSettings"; import { Settings } from "./Settings"; -export const SettingsOverview = () => { +export function SettingsOverview() { const settingsQuery = useSettings(); return ( @@ -10,4 +10,4 @@ export const SettingsOverview = () => { ); -}; +} diff --git a/vinvoor/src/settings/admin/Admin.tsx b/vinvoor/src/settings/admin/Admin.tsx index 246665b..1f944a8 100644 --- a/vinvoor/src/settings/admin/Admin.tsx +++ b/vinvoor/src/settings/admin/Admin.tsx @@ -1,5 +1,5 @@ +import type { FC } from "react"; import { Alert, Grid, Typography } from "@mui/material"; -import { FC } from "react"; import { Days } from "./days/Days"; import { Seasons } from "./seasons/Seasons"; diff --git a/vinvoor/src/settings/admin/days/Days.tsx b/vinvoor/src/settings/admin/days/Days.tsx index b495276..d757cf4 100644 --- a/vinvoor/src/settings/admin/days/Days.tsx +++ b/vinvoor/src/settings/admin/days/Days.tsx @@ -1,10 +1,10 @@ import { Grid } from "@mui/material"; import { LoadingSkeleton } from "../../../components/LoadingSkeleton"; +import { useAdminDays } from "../../../hooks/admin/useAdminDays"; import { DaysAdd } from "./DaysAdd"; import { DaysTable } from "./DaysTable"; -import { useAdminDays } from "../../../hooks/admin/useAdminDays"; -export const Days = () => { +export function Days() { const daysQuery = useAdminDays(); return ( @@ -24,4 +24,4 @@ export const Days = () => { ); -}; +} diff --git a/vinvoor/src/settings/admin/days/DaysAdd.tsx b/vinvoor/src/settings/admin/days/DaysAdd.tsx index 26000e2..9fef7ea 100644 --- a/vinvoor/src/settings/admin/days/DaysAdd.tsx +++ b/vinvoor/src/settings/admin/days/DaysAdd.tsx @@ -1,16 +1,18 @@ +import type { Dayjs } from "dayjs"; +import type { Dispatch, SetStateAction } from "react"; import { Box, Button, Paper, Stack } from "@mui/material"; import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; -import dayjs, { Dayjs } from "dayjs"; +import dayjs from "dayjs"; import { useSnackbar } from "notistack"; -import { Dispatch, SetStateAction, useState } from "react"; +import { useState } from "react"; import { TypographyG } from "../../../components/TypographyG"; import { useAdminAddDay, useAdminDays, } from "../../../hooks/admin/useAdminDays"; -export const DaysAdd = () => { +export function DaysAdd() { const { refetch } = useAdminDays(); const addDay = useAdminAddDay(); const [startDate, setStartDate] = useState(dayjs()); @@ -85,4 +87,4 @@ export const DaysAdd = () => { ); -}; +} diff --git a/vinvoor/src/settings/admin/days/DaysTable.tsx b/vinvoor/src/settings/admin/days/DaysTable.tsx index 42e3667..8a3da5d 100644 --- a/vinvoor/src/settings/admin/days/DaysTable.tsx +++ b/vinvoor/src/settings/admin/days/DaysTable.tsx @@ -1,46 +1,46 @@ +import type { ChangeEvent } from "react"; +import type { Day } from "../../../types/days"; +import type { Optional } from "../../../types/general"; import { Paper, Stack, Table, TableContainer } from "@mui/material"; import { useSnackbar } from "notistack"; -import { ChangeEvent, useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import { TypographyG } from "../../../components/TypographyG"; -import { Day } from "../../../types/days"; -import { Optional } from "../../../types/general"; -import { randomInt } from "../../../util/util"; -import { DaysTableBody } from "./DaysTableBody"; -import { DaysTableHead } from "./DaysTableHead"; -import { DaysTableToolbar } from "./DaysTableToolbar"; import { useAdminDays, useAdminDeleteDay, } from "../../../hooks/admin/useAdminDays"; import { useAdminSeasons } from "../../../hooks/admin/useAdminSeason"; +import { randomInt } from "../../../util/util"; +import { DaysTableBody } from "./DaysTableBody"; +import { DaysTableHead } from "./DaysTableHead"; +import { DaysTableToolbar } from "./DaysTableToolbar"; -export const DaysTable = () => { +export function DaysTable() { const { data: days, refetch } = useAdminDays(); const { data: seasons } = useAdminSeasons(); - if (!days) return null; // Can never happen const deleteDay = useAdminDeleteDay(); - const [rows, setRows] = useState(days); + const [rows, setRows] = useState(days ?? []); const [selected, setSelected] = useState([]); const [deleting, setDeleting] = useState(false); const [dateFilter, setDateFilter] = useState< [Optional, Optional] >([undefined, undefined]); - const [seasonsFilter, setSeasonsFilter] = - useState>(undefined); + const [seasonsFilter, setSeasonsFilter] + = useState>(undefined); const [weekdaysFilter, setWeekdaysFilter] = useState(false); const [weekendsFilter, setWeekendsFilter] = useState(false); const { enqueueSnackbar, closeSnackbar } = useSnackbar(); const filterDays = (): readonly Day[] => { - let filteredDays = [...days]; + let filteredDays = [...days ?? []]; if (dateFilter[0] !== undefined && dateFilter[1] !== undefined) { filteredDays = filteredDays.filter( day => - day.date.getTime() >= dateFilter[0]!.getTime() && - day.date.getTime() <= dateFilter[1]!.getTime(), + day.date.getTime() >= dateFilter[0]!.getTime() + && day.date.getTime() <= dateFilter[1]!.getTime(), ); } if (seasonsFilter) { @@ -65,12 +65,20 @@ export const DaysTable = () => { return filteredDays; }; + useEffect( + () => setRows(filterDays()), + [days, dateFilter, seasonsFilter, weekdaysFilter, weekendsFilter], + ); + + if (!days) + return null; // Can never happen + const handleDelete = () => { setDeleting(true); const key = randomInt(); enqueueSnackbar("Deleting...", { variant: "info", - key: key, + key, persist: true, }); @@ -127,17 +135,13 @@ export const DaysTable = () => { }; const handleSelectAll = (event: ChangeEvent) => { - if (event.target.checked) setSelected(rows.map(day => day.id)); + if (event.target.checked) + setSelected(rows.map(day => day.id)); else setSelected([]); }; const isSelected = (id: number) => selected.includes(id); - useEffect( - () => setRows(filterDays()), - [days, dateFilter, seasonsFilter, weekdaysFilter, weekendsFilter], - ); - return ( { ); -}; +} diff --git a/vinvoor/src/settings/admin/days/DaysTableBody.tsx b/vinvoor/src/settings/admin/days/DaysTableBody.tsx index b83de5a..af5c6c8 100644 --- a/vinvoor/src/settings/admin/days/DaysTableBody.tsx +++ b/vinvoor/src/settings/admin/days/DaysTableBody.tsx @@ -1,3 +1,5 @@ +import type { FC, ReactNode } from "react"; +import type { Day } from "../../../types/days"; import DeleteIcon from "@mui/icons-material/Delete"; import { Checkbox, @@ -8,12 +10,11 @@ import { Typography, } from "@mui/material"; import { useSnackbar } from "notistack"; -import { FC, ReactNode } from "react"; -import { Day, daysHeadCells } from "../../../types/days"; import { useAdminDays, useAdminDeleteDay, } from "../../../hooks/admin/useAdminDays"; +import { daysHeadCells } from "../../../types/days"; interface DaysTableBodyProps { rows: readonly Day[]; @@ -34,7 +35,8 @@ export const DaysTableBody: FC = ({ const { enqueueSnackbar } = useSnackbar(); const handleClick = (id: number) => { - if (isSelected(id)) handleSelect(id); // This will remove it from the selected list + if (isSelected(id)) + handleSelect(id); // This will remove it from the selected list deleteDay.mutate(id, { onSuccess: () => { diff --git a/vinvoor/src/settings/admin/days/DaysTableHead.tsx b/vinvoor/src/settings/admin/days/DaysTableHead.tsx index 14f7412..d169d7a 100644 --- a/vinvoor/src/settings/admin/days/DaysTableHead.tsx +++ b/vinvoor/src/settings/admin/days/DaysTableHead.tsx @@ -1,3 +1,4 @@ +import type { ChangeEvent, FC } from "react"; import { Box, Button, @@ -7,7 +8,6 @@ import { TableRow, Typography, } from "@mui/material"; -import { ChangeEvent, FC } from "react"; import { daysHeadCells } from "../../../types/days"; interface DaysTableHeadProps { @@ -50,9 +50,11 @@ export const DaysTableHead: FC = ({ variant="outlined" disabled={numSelected === 0 || deleting} onClick={handleDelete} - >{`Delet${deleting ? "ing" : "e"} ${numSelected} ${ - deleting ? "..." : "" - }`} + > + {`Delet${deleting ? "ing" : "e"} ${numSelected} ${ + deleting ? "..." : "" + }`} + diff --git a/vinvoor/src/settings/admin/days/DaysTableToolbar.tsx b/vinvoor/src/settings/admin/days/DaysTableToolbar.tsx index fa0f17d..9411944 100644 --- a/vinvoor/src/settings/admin/days/DaysTableToolbar.tsx +++ b/vinvoor/src/settings/admin/days/DaysTableToolbar.tsx @@ -1,16 +1,20 @@ +import type { + SelectChangeEvent, +} from "@mui/material"; +import type { Dayjs } from "dayjs"; +import type { ChangeEvent, Dispatch, FC, SetStateAction } from "react"; +import type { Optional } from "../../../types/general"; import { Checkbox, MenuItem, Select, - SelectChangeEvent, Stack, Typography, } from "@mui/material"; import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; -import dayjs, { Dayjs } from "dayjs"; -import { ChangeEvent, Dispatch, FC, SetStateAction, useState } from "react"; -import { Optional } from "../../../types/general"; +import dayjs from "dayjs"; +import { useState } from "react"; import { useAdminDays } from "../../../hooks/admin/useAdminDays"; import { useAdminSeasons } from "../../../hooks/admin/useAdminSeason"; @@ -37,17 +41,19 @@ export const DaysTableToolbar: FC = ({ }) => { const { data: days } = useAdminDays(); const { data: seasons } = useAdminSeasons(); - if (!days || !seasons) return null; // Can never happen const [startDate, setStartDate] = useState( - days.length ? dayjs(days[0].date) : dayjs(), + days?.length ? dayjs(days[0].date) : dayjs(), ); const [endDate, setEndDate] = useState( - days.length ? dayjs(days[days.length - 1].date) : dayjs(), + days?.length ? dayjs(days[days.length - 1].date) : dayjs(), ); - const [selectedSeason, setSelectedSeason] = - useState>(seasonFilter); + const [selectedSeason, setSelectedSeason] + = useState>(seasonFilter); + + if (!days || !seasons) + return null; // Can never happen const handleDateChange = ( date: Dayjs | null, @@ -70,10 +76,11 @@ export const DaysTableToolbar: FC = ({ }; const handleSeasonChange = (event: SelectChangeEvent) => - setSelectedSeason(parseInt(event.target.value)); + setSelectedSeason(Number.parseInt(event.target.value)); const handleClickSeason = (event: ChangeEvent) => { - if (event.target.checked) setSeasonFilter(selectedSeason); + if (event.target.checked) + setSeasonFilter(selectedSeason); else setSeasonFilter(undefined); }; @@ -119,7 +126,8 @@ export const DaysTableToolbar: FC = ({ value={ seasons .find(season => season.id === selectedSeason) - ?.id.toString() ?? seasons[0].id.toString() + ?.id + .toString() ?? seasons[0].id.toString() } onChange={handleSeasonChange} > diff --git a/vinvoor/src/settings/admin/seasons/Seasons.tsx b/vinvoor/src/settings/admin/seasons/Seasons.tsx index e02dd61..bf729c6 100644 --- a/vinvoor/src/settings/admin/seasons/Seasons.tsx +++ b/vinvoor/src/settings/admin/seasons/Seasons.tsx @@ -1,10 +1,10 @@ import { Grid } from "@mui/material"; import { LoadingSkeleton } from "../../../components/LoadingSkeleton"; -import { SeasonsTable } from "./SeasonsTable"; -import { SeasonsAdd } from "./SeasonsAdd"; import { useAdminSeasons } from "../../../hooks/admin/useAdminSeason"; +import { SeasonsAdd } from "./SeasonsAdd"; +import { SeasonsTable } from "./SeasonsTable"; -export const Seasons = () => { +export function Seasons() { const seasonsQuery = useAdminSeasons(); return ( @@ -24,4 +24,4 @@ export const Seasons = () => { ); -}; +} diff --git a/vinvoor/src/settings/admin/seasons/SeasonsAdd.tsx b/vinvoor/src/settings/admin/seasons/SeasonsAdd.tsx index f308d4a..6168982 100644 --- a/vinvoor/src/settings/admin/seasons/SeasonsAdd.tsx +++ b/vinvoor/src/settings/admin/seasons/SeasonsAdd.tsx @@ -1,16 +1,18 @@ -import dayjs, { Dayjs } from "dayjs"; -import { - useAdminAddSeason, - useAdminSeasons, -} from "../../../hooks/admin/useAdminSeason"; -import { Dispatch, SetStateAction, useState } from "react"; -import { useSnackbar } from "notistack"; +import type { Dayjs } from "dayjs"; +import type { Dispatch, SetStateAction } from "react"; import { Box, Button, Paper, Stack, TextField } from "@mui/material"; import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import dayjs from "dayjs"; +import { useSnackbar } from "notistack"; +import { useState } from "react"; import { TypographyG } from "../../../components/TypographyG"; +import { + useAdminAddSeason, + useAdminSeasons, +} from "../../../hooks/admin/useAdminSeason"; -export const SeasonsAdd = () => { +export function SeasonsAdd() { const { refetch } = useAdminSeasons(); const addSeason = useAdminAddSeason(); const [startDate, setStartDate] = useState(dayjs()); @@ -95,4 +97,4 @@ export const SeasonsAdd = () => { ); -}; +} diff --git a/vinvoor/src/settings/admin/seasons/SeasonsTable.tsx b/vinvoor/src/settings/admin/seasons/SeasonsTable.tsx index 1963ad3..a3fb173 100644 --- a/vinvoor/src/settings/admin/seasons/SeasonsTable.tsx +++ b/vinvoor/src/settings/admin/seasons/SeasonsTable.tsx @@ -1,31 +1,32 @@ +import type { ChangeEvent } from "react"; import { Paper, Stack, Table, TableContainer } from "@mui/material"; -import { TypographyG } from "../../../components/TypographyG"; -import { ChangeEvent, useState } from "react"; -import { randomInt } from "../../../util/util"; import { useSnackbar } from "notistack"; +import { useState } from "react"; +import { TypographyG } from "../../../components/TypographyG"; import { useAdminDeleteSeason, useAdminSeasons, } from "../../../hooks/admin/useAdminSeason"; -import { SeasonsTableHead } from "./SeasonsTableHead"; +import { randomInt } from "../../../util/util"; import { SeasonsTableBody } from "./SeasonsTableBody"; +import { SeasonsTableHead } from "./SeasonsTableHead"; -export const SeasonsTable = () => { +export function SeasonsTable() { const { data: seasons, refetch } = useAdminSeasons(); - if (!seasons) return null; // Can never happen - const deleteSeason = useAdminDeleteSeason(); const [selected, setSelected] = useState([]); const [deleting, setDeleting] = useState(false); - const { enqueueSnackbar, closeSnackbar } = useSnackbar(); + if (!seasons) + return null; // Can never happen + const handleDelete = () => { setDeleting(true); const key = randomInt(); enqueueSnackbar("Deleting...", { variant: "info", - key: key, + key, persist: true, }); @@ -79,7 +80,8 @@ export const SeasonsTable = () => { }; const handleSelectAll = (event: ChangeEvent) => { - if (event.target.checked) setSelected(seasons.map(season => season.id)); + if (event.target.checked) + setSelected(seasons.map(season => season.id)); else setSelected([]); }; @@ -115,4 +117,4 @@ export const SeasonsTable = () => { ); -}; +} diff --git a/vinvoor/src/settings/admin/seasons/SeasonsTableBody.tsx b/vinvoor/src/settings/admin/seasons/SeasonsTableBody.tsx index 0409a96..0b31ec9 100644 --- a/vinvoor/src/settings/admin/seasons/SeasonsTableBody.tsx +++ b/vinvoor/src/settings/admin/seasons/SeasonsTableBody.tsx @@ -1,3 +1,5 @@ +import type { FC, ReactNode } from "react"; +import DeleteIcon from "@mui/icons-material/Delete"; import { Checkbox, IconButton, @@ -6,8 +8,6 @@ import { TableRow, Typography, } from "@mui/material"; -import DeleteIcon from "@mui/icons-material/Delete"; -import { FC, ReactNode } from "react"; import { useSnackbar } from "notistack"; import { useAdminDeleteSeason, @@ -27,14 +27,15 @@ export const SeasonsTableBody: FC = ({ deleting, }) => { const { data: seasons, refetch } = useAdminSeasons(); - if (!seasons) return null; // Can never happen - const deleteSeason = useAdminDeleteSeason(); const { enqueueSnackbar } = useSnackbar(); + if (!seasons) + return null; // Can never happen + const handleClick = (id: number) => { - console.log("Hi"); - if (isSelected(id)) handleSelect(id); // This will remove it from the selected list + if (isSelected(id)) + handleSelect(id); // This will remove it from the selected list deleteSeason.mutate(id, { onSuccess: () => { diff --git a/vinvoor/src/settings/admin/seasons/SeasonsTableHead.tsx b/vinvoor/src/settings/admin/seasons/SeasonsTableHead.tsx index 91c40b5..4e58828 100644 --- a/vinvoor/src/settings/admin/seasons/SeasonsTableHead.tsx +++ b/vinvoor/src/settings/admin/seasons/SeasonsTableHead.tsx @@ -1,3 +1,4 @@ +import type { ChangeEvent, FC } from "react"; import { Box, Button, @@ -7,7 +8,6 @@ import { TableRow, Typography, } from "@mui/material"; -import { ChangeEvent, FC } from "react"; import { seasonsHeadCells } from "../../../types/seasons"; interface SeasonsTableHeadProps { @@ -50,9 +50,11 @@ export const SeasonsTableHead: FC = ({ variant="outlined" disabled={numSelected === 0 || deleting} onClick={handleDelete} - >{`Delet${deleting ? "ing" : "e"} ${numSelected} ${ - deleting ? "..." : "" - }`} + > + {`Delet${deleting ? "ing" : "e"} ${numSelected} ${ + deleting ? "..." : "" + }`} + diff --git a/vinvoor/src/themes/theme.ts b/vinvoor/src/themes/theme.ts index 866fc4a..0034e20 100644 --- a/vinvoor/src/themes/theme.ts +++ b/vinvoor/src/themes/theme.ts @@ -1,4 +1,5 @@ -import { createTheme, ThemeOptions } from "@mui/material"; +import type { ThemeOptions } from "@mui/material"; +import { createTheme } from "@mui/material"; const baseTheme: ThemeOptions = { palette: { @@ -134,7 +135,7 @@ export const kakTheme = createTheme({ MuiButton: { styleOverrides: { outlined: { - borderWidth: "2px", + "borderWidth": "2px", "&:hover": { borderWidth: "2px", }, diff --git a/vinvoor/src/types/cards.ts b/vinvoor/src/types/cards.ts index a105562..a7afca2 100644 --- a/vinvoor/src/types/cards.ts +++ b/vinvoor/src/types/cards.ts @@ -1,4 +1,4 @@ -import { Base, BaseJSON, TableHeadCell } from "./general"; +import type { Base, BaseJSON, TableHeadCell } from "./general"; // External @@ -46,28 +46,29 @@ export interface CardGetRegisterResponse { // Converters -export const convertCardJSON = (cardsJSON: CardJSON[]): Card[] => - cardsJSON.map(cardJSON => ({ +export function convertCardJSON(cardsJSON: CardJSON[]): Card[] { + return cardsJSON.map(cardJSON => ({ ...cardJSON, lastUsed: new Date(cardJSON.last_used), amountUsed: cardJSON.amount_used, createdAt: new Date(cardJSON.created_at), })); +} -export const convertCardPostResponseJSON = ( - cardJSON: CardPostResponseJSON, -): CardPostResponse => ({ - isCurrentUser: cardJSON.is_current_user, -}); +export function convertCardPostResponseJSON(cardJSON: CardPostResponseJSON): CardPostResponse { + return { + isCurrentUser: cardJSON.is_current_user, + }; +} -export const convertCardGetRegisterResponseJSON = ( - cardJSON: CardGetRegisterResponseJSON, -): CardGetRegisterResponse => ({ - ...cardJSON, - isCurrentUser: cardJSON.is_current_user, - timeRemaining: cardJSON.time_remaining, - timePercentage: cardJSON.time_percentage, -}); +export function convertCardGetRegisterResponseJSON(cardJSON: CardGetRegisterResponseJSON): CardGetRegisterResponse { + return { + ...cardJSON, + isCurrentUser: cardJSON.is_current_user, + timeRemaining: cardJSON.time_remaining, + timePercentage: cardJSON.time_percentage, + }; +} // Table @@ -90,7 +91,8 @@ export const cardsHeadCells: readonly TableHeadCell[] = [ align: "right", padding: "normal", convert: (value: Date) => { - if (value.getFullYear() === 1) return "Not used"; + if (value.getFullYear() === 1) + return "Not used"; else return value.toDateString(); }, } as TableHeadCell, diff --git a/vinvoor/src/types/days.ts b/vinvoor/src/types/days.ts index 6824549..43d5653 100644 --- a/vinvoor/src/types/days.ts +++ b/vinvoor/src/types/days.ts @@ -1,4 +1,4 @@ -import { Base, BaseJSON, TableHeadCell } from "./general"; +import type { Base, BaseJSON, TableHeadCell } from "./general"; // External @@ -14,13 +14,14 @@ export interface Day extends Base { // Converters -export const convertDayJSON = (daysJSON: DayJSON[]): Day[] => - daysJSON +export function convertDayJSON(daysJSON: DayJSON[]): Day[] { + return daysJSON .map(dayJSON => ({ ...dayJSON, date: new Date(dayJSON.date), })) .sort((a, b) => a.date.getTime() - b.date.getTime()); +} // Table diff --git a/vinvoor/src/types/leaderboard.ts b/vinvoor/src/types/leaderboard.ts index 376916b..ffb6a06 100644 --- a/vinvoor/src/types/leaderboard.ts +++ b/vinvoor/src/types/leaderboard.ts @@ -1,4 +1,4 @@ -import { TableHeadCell } from "./general"; +import type { TableHeadCell } from "./general"; // External @@ -22,14 +22,13 @@ export interface LeaderboardItem { // Converters -export const convertLeaderboardItemJSON = ( - leaderboardItems: LeaderboardItemJSON[], -): LeaderboardItem[] => - leaderboardItems.map(leaderboardItem => ({ +export function convertLeaderboardItemJSON(leaderboardItems: LeaderboardItemJSON[]): LeaderboardItem[] { + return leaderboardItems.map(leaderboardItem => ({ ...leaderboardItem, totalDays: leaderboardItem.total_days, positionChange: leaderboardItem.position_change, })); +} // Table diff --git a/vinvoor/src/types/scans.ts b/vinvoor/src/types/scans.ts index 6e2fe7e..d6c67a2 100644 --- a/vinvoor/src/types/scans.ts +++ b/vinvoor/src/types/scans.ts @@ -1,6 +1,6 @@ +import type { Card } from "./cards"; +import type { Base, BaseJSON, TableHeadCell } from "./general"; import { dateTimeFormat } from "../util/util"; -import { Card } from "./cards"; -import { Base, BaseJSON, TableHeadCell } from "./general"; // External @@ -25,8 +25,8 @@ export interface ScanCard { // Converters -export const convertScanJSON = (scansJSON: ScanJSON[]): Scan[] => - scansJSON +export function convertScanJSON(scansJSON: ScanJSON[]): Scan[] { + return scansJSON .map(scanJSON => ({ ...scanJSON, scanTime: new Date(scanJSON.scan_time), @@ -34,6 +34,7 @@ export const convertScanJSON = (scansJSON: ScanJSON[]): Scan[] => createdAt: new Date(scanJSON.created_at), })) .sort((a, b) => a.scanTime.getTime() - b.scanTime.getTime()); +} // Table @@ -56,11 +57,9 @@ export const scanCardHeadCells: readonly TableHeadCell[] = [ // Other -export const mergeScansCards = ( - scans: readonly Scan[], - cards: readonly Card[], -): ScanCard[] => - scans.map(scan => ({ +export function mergeScansCards(scans: readonly Scan[], cards: readonly Card[]): ScanCard[] { + return scans.map(scan => ({ scanTime: scan.scanTime, card: cards.find(card => card.serial === scan.cardSerial), })); +} diff --git a/vinvoor/src/types/seasons.ts b/vinvoor/src/types/seasons.ts index a1baf91..529ada9 100644 --- a/vinvoor/src/types/seasons.ts +++ b/vinvoor/src/types/seasons.ts @@ -1,4 +1,4 @@ -import { Base, BaseJSON, TableHeadCell } from "./general"; +import type { Base, BaseJSON, TableHeadCell } from "./general"; // External @@ -20,13 +20,14 @@ export interface Season extends Base { // Converters -export const convertSeasonJSON = (seasonsJSON: SeasonJSON[]): Season[] => - seasonsJSON.map(seasonJSON => ({ +export function convertSeasonJSON(seasonsJSON: SeasonJSON[]): Season[] { + return seasonsJSON.map(seasonJSON => ({ ...seasonJSON, start: new Date(seasonJSON.start), end: new Date(seasonJSON.end), isCurrent: seasonJSON.is_current, })); +} // Table diff --git a/vinvoor/src/types/settings.ts b/vinvoor/src/types/settings.ts index c121da1..cf8555e 100644 --- a/vinvoor/src/types/settings.ts +++ b/vinvoor/src/types/settings.ts @@ -12,6 +12,8 @@ export interface Settings { // Converters -export const converSettingsJSON = (settingsJSON: SettingsJSON): Settings => ({ - ...settingsJSON, -}); +export function converSettingsJSON(settingsJSON: SettingsJSON): Settings { + return { + ...settingsJSON, + }; +} diff --git a/vinvoor/src/types/version.ts b/vinvoor/src/types/version.ts index 7cdc308..96cfd2b 100644 --- a/vinvoor/src/types/version.ts +++ b/vinvoor/src/types/version.ts @@ -12,6 +12,8 @@ export interface Version { // Converters -export const convertVersionJSON = (versionJSON: VersionJSON): Version => ({ - ...versionJSON, -}); +export function convertVersionJSON(versionJSON: VersionJSON): Version { + return { + ...versionJSON, + }; +} diff --git a/vinvoor/src/util/fetch.ts b/vinvoor/src/util/fetch.ts index f2e34ed..39dd217 100644 --- a/vinvoor/src/util/fetch.ts +++ b/vinvoor/src/util/fetch.ts @@ -2,17 +2,12 @@ const URLS: Record = { API: import.meta.env.VITE_BACKEND_URL as string, }; -export const getApi = ( - endpoint: string, - convertData?: (data: U) => T, -) => _fetch(`${URLS.API}/${endpoint}`, {}, convertData); +export async function getApi(endpoint: string, convertData?: (data: U) => T) { + return _fetch(`${URLS.API}/${endpoint}`, {}, convertData); +} -export const postApi = ( - endpoint: string, - body: Record = {}, - convertData?: (data: U) => T, -) => - _fetch( +export async function postApi(endpoint: string, body: Record = {}, convertData?: (data: U) => T) { + return _fetch( `${URLS.API}/${endpoint}`, { method: "POST", @@ -21,13 +16,10 @@ export const postApi = ( }, convertData, ); +} -export const patchApi = ( - endpoint: string, - body: Record = {}, - convertData?: (data: U) => T, -) => - _fetch( +export async function patchApi(endpoint: string, body: Record = {}, convertData?: (data: U) => T) { + return _fetch( `${URLS.API}/${endpoint}`, { method: "PATCH", @@ -36,36 +28,30 @@ export const patchApi = ( }, convertData, ); +} -export const deleteAPI = ( - endpoint: string, - body: Record = {}, -) => - _fetch(`${URLS.API}/${endpoint}`, { +export async function deleteAPI(endpoint: string, body: Record = {}) { + return _fetch(`${URLS.API}/${endpoint}`, { method: "DELETE", body: JSON.stringify(body), headers: new Headers({ "content-type": "application/json" }), }); +} interface ResponseNot200Error extends Error { response: Response; } -export const isResponseNot200Error = ( - error: unknown, -): error is ResponseNot200Error => - (error as ResponseNot200Error).response !== undefined; +export function isResponseNot200Error(error: unknown): error is ResponseNot200Error { + return (error as ResponseNot200Error).response !== undefined; +} -const _fetch = async ( - url: string, - options: RequestInit = {}, - convertData?: (data: U) => T, -): Promise => - fetch(url, { credentials: "include", ...options }) - .then(response => { +async function _fetch(url: string, options: RequestInit = {}, convertData?: (data: U) => T): Promise { + return fetch(url, { credentials: "include", ...options }) + .then(async (response) => { if (!response.ok) { const error = new Error( - "Fetch failed with status: " + response.status, + `Fetch failed with status: ${response.status}`, ) as ResponseNot200Error; error.response = response; throw error; @@ -73,8 +59,12 @@ const _fetch = async ( const contentType = response.headers.get("content-type"); - return contentType?.includes("application/json") - ? response.json() - : response.text(); + if (contentType?.includes("application/json")) + return response.json() as Promise; + else if (contentType?.includes("image/png")) + return response.blob(); + else + return response.text(); }) .then(data => (convertData ? convertData(data as U) : (data as T))); +} diff --git a/vinvoor/src/util/util.ts b/vinvoor/src/util/util.ts index 450bf78..fea8a86 100644 --- a/vinvoor/src/util/util.ts +++ b/vinvoor/src/util/util.ts @@ -1,21 +1,22 @@ -export const randomInt = (lower = 0, upper = 10000): number => { +export function randomInt(lower = 0, upper = 10000): number { return Math.floor(Math.random() * (upper - lower + 1) + lower); -}; +} // Date functions export const MILLISECONDS_IN_ONE_DAY = 24 * 60 * 60 * 1000; -export const isTheSameDay = (date1: Date, date2: Date) => - date1.getFullYear() === date2.getFullYear() && - date1.getMonth() === date2.getMonth() && - date1.getDate() === date2.getDate(); +export function isTheSameDay(date1: Date, date2: Date) { + return date1.getFullYear() === date2.getFullYear() + && date1.getMonth() === date2.getMonth() + && date1.getDate() === date2.getDate(); +} -export const shiftDate = (date: Date, numDays: number) => { +export function shiftDate(date: Date, numDays: number) { const newDate = new Date(date); newDate.setDate(newDate.getDate() + numDays); return newDate; -}; +} export const dateTimeFormat = new Intl.DateTimeFormat("en-GB", { year: "2-digit", @@ -27,42 +28,45 @@ export const dateTimeFormat = new Intl.DateTimeFormat("en-GB", { // Compare functions -export const equal = (left: unknown, right: unknown): boolean => { - if (typeof left !== typeof right) return false; +export function equal(left: unknown, right: unknown): boolean { + if (typeof left !== typeof right) + return false; if (Array.isArray(left) && Array.isArray(right)) return equalArray(left, right); - if (typeof left === "object" && left !== null && right !== null) + if (typeof left === "object" && left !== null && right !== null) { return equalObject( left as Record, right as Record, ); + } return left === right; -}; +} -const equalArray = (left: unknown[], right: unknown[]): boolean => { - if (left.length !== right.length) return false; +function equalArray(left: unknown[], right: unknown[]): boolean { + if (left.length !== right.length) + return false; for (let i = 0; i < left.length; i++) { - if (!equal(left[i], right[i])) return false; + if (!equal(left[i], right[i])) + return false; } return true; -}; +} -const equalObject = ( - left: Record, - right: Record, -): boolean => { +function equalObject(left: Record, right: Record): boolean { const leftKeys = Object.keys(left); const rightKeys = Object.keys(right); - if (leftKeys.length !== rightKeys.length) return false; + if (leftKeys.length !== rightKeys.length) + return false; for (const key of leftKeys) { - if (!equal(left[key], right[key])) return false; + if (!equal(left[key], right[key])) + return false; } return true; -}; +} diff --git a/vinvoor/tsconfig.json b/vinvoor/tsconfig.json index c5f9626..2ff90e9 100644 --- a/vinvoor/tsconfig.json +++ b/vinvoor/tsconfig.json @@ -1,25 +1,29 @@ { "compilerOptions": { "target": "ES2020", - "useDefineForClassFields": true, + "jsx": "react-jsx", "lib": ["ES2020", "DOM", "DOM.Iterable"], + "moduleDetection": "force", + "useDefineForClassFields": true, + "baseUrl": ".", "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, + "moduleResolution": "Bundler", + "paths": { + "@/*": ["./src/*"] + }, "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - - /* Linting */ + "allowImportingTsExtensions": true, + "allowJs": true, "strict": true, + "strictNullChecks": true, + "noFallthroughCasesInSwitch": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true + "noEmit": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "skipLibCheck": true }, - "include": ["src", "eslint.config.mjs"], - "references": [{ "path": "./tsconfig.node.json" }] + "exclude": ["dist", "node_modules", "cypress"] } diff --git a/vinvoor/tsconfig.node.json b/vinvoor/tsconfig.node.json index 97ede7e..38a9d93 100644 --- a/vinvoor/tsconfig.node.json +++ b/vinvoor/tsconfig.node.json @@ -1,11 +1,11 @@ { "compilerOptions": { "composite": true, - "skipLibCheck": true, "module": "ESNext", "moduleResolution": "bundler", + "strict": true, "allowSyntheticDefaultImports": true, - "strict": true + "skipLibCheck": true }, "include": ["vite.config.ts"] } From 0102d55547064d710cbda29356acc7c85c0ea047 Mon Sep 17 00:00:00 2001 From: Topvennie Date: Tue, 19 Nov 2024 13:10:40 +0100 Subject: [PATCH 3/3] vinvoor: deps --- vinvoor/package.json | 23 +- vinvoor/pnpm-lock.yaml | 1675 +++++++++++++++++++++++++---- vinvoor/src/settings/Settings.tsx | 3 + 3 files changed, 1464 insertions(+), 237 deletions(-) diff --git a/vinvoor/package.json b/vinvoor/package.json index edac4b6..dd053f2 100644 --- a/vinvoor/package.json +++ b/vinvoor/package.json @@ -1,15 +1,18 @@ { "name": "vinvoor", "type": "module", - "version": "0.0.0", + "version": "0.1.0", "private": true, "scripts": { "dev": "vite", "host": "vite --host", "build": "tsc && vite build", - "format": "prettier . --write", - "lint": "eslint . --fix", - "preview": "vite preview" + "lint": "eslint . && tsc --noEmit", + "lint:fix": "eslint . --fix", + "typecheck": "tsc --noEmit", + "preview": "vite preview", + "precommit:lint": "eslint .", + "precommit:typecheck": "tsc --noEmit" }, "dependencies": { "@emotion/react": "^11.13.3", @@ -18,7 +21,7 @@ "@mui/icons-material": "^5.16.7", "@mui/material": "^5.16.7", "@mui/x-date-pickers": "^7.22.2", - "@tanstack/react-query": "^5.60.5", + "@tanstack/react-query": "^5.60.6", "@types/js-cookie": "^3.0.6", "@types/react-router-dom": "^5.3.3", "@types/react-router-hash-link": "^2.4.9", @@ -36,18 +39,16 @@ "react-tooltip": "^5.28.0" }, "devDependencies": { - "@eslint/compat": "^1.2.3", - "@eslint/js": "^9.15.0", - "@types/eslint__js": "^8.42.3", + "@antfu/eslint-config": "^3.9.2", + "@eslint-react/eslint-plugin": "^1.16.1", "@types/node": "^22.9.0", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "@vitejs/plugin-react-swc": "^3.7.1", "eslint": "^9.15.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-format": "^0.1.2", + "eslint-plugin-react-hooks": "5.1.0-beta-26f2496093-20240514", "eslint-plugin-react-refresh": "^0.4.14", - "prettier": "3.3.3", "typescript": "^5.6.3", "typescript-eslint": "^8.15.0", "vite": "^5.4.11", diff --git a/vinvoor/pnpm-lock.yaml b/vinvoor/pnpm-lock.yaml index fdd5c01..e67605b 100644 --- a/vinvoor/pnpm-lock.yaml +++ b/vinvoor/pnpm-lock.yaml @@ -27,8 +27,8 @@ importers: specifier: ^7.22.2 version: 7.22.2(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(dayjs@1.11.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/react-query': - specifier: ^5.60.5 - version: 5.60.5(react@18.3.1) + specifier: ^5.60.6 + version: 5.60.6(react@18.3.1) '@types/js-cookie': specifier: ^3.0.6 version: 3.0.6 @@ -75,15 +75,12 @@ importers: specifier: ^5.28.0 version: 5.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: - '@eslint/compat': - specifier: ^1.2.3 - version: 1.2.3(eslint@9.15.0) - '@eslint/js': - specifier: ^9.15.0 - version: 9.15.0 - '@types/eslint__js': - specifier: ^8.42.3 - version: 8.42.3 + '@antfu/eslint-config': + specifier: ^3.9.2 + version: 3.9.2(@eslint-react/eslint-plugin@1.16.1(eslint@9.15.0)(typescript@5.6.3))(@typescript-eslint/utils@8.15.0(eslint@9.15.0)(typescript@5.6.3))(@vue/compiler-sfc@3.5.13)(eslint-plugin-format@0.1.2(eslint@9.15.0))(eslint-plugin-react-hooks@5.1.0-beta-26f2496093-20240514(eslint@9.15.0))(eslint-plugin-react-refresh@0.4.14(eslint@9.15.0))(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/eslint-plugin': + specifier: ^1.16.1 + version: 1.16.1(eslint@9.15.0)(typescript@5.6.3) '@types/node': specifier: ^22.9.0 version: 22.9.0 @@ -93,30 +90,21 @@ importers: '@types/react-dom': specifier: ^18.3.1 version: 18.3.1 - '@typescript-eslint/eslint-plugin': - specifier: ^7.18.0 - version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3) - '@typescript-eslint/parser': - specifier: ^7.18.0 - version: 7.18.0(eslint@9.15.0)(typescript@5.6.3) '@vitejs/plugin-react-swc': specifier: ^3.7.1 version: 3.7.1(vite@5.4.11(@types/node@22.9.0)) eslint: specifier: ^9.15.0 version: 9.15.0 - eslint-config-prettier: - specifier: ^9.1.0 - version: 9.1.0(eslint@9.15.0) + eslint-plugin-format: + specifier: ^0.1.2 + version: 0.1.2(eslint@9.15.0) eslint-plugin-react-hooks: - specifier: ^4.6.2 - version: 4.6.2(eslint@9.15.0) + specifier: 5.1.0-beta-26f2496093-20240514 + version: 5.1.0-beta-26f2496093-20240514(eslint@9.15.0) eslint-plugin-react-refresh: specifier: ^0.4.14 version: 0.4.14(eslint@9.15.0) - prettier: - specifier: 3.3.3 - version: 3.3.3 typescript: specifier: ^5.6.3 version: 5.6.3 @@ -136,6 +124,58 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@antfu/eslint-config@3.9.2': + resolution: {integrity: sha512-a1I1CXmtQdTL9jxcb2RzKjuYYAzjdKK3ktVpQGd/1S/aUdhKgcEEi3DRXYgnB8xdpYLqracETxEMDf9PQlmyBg==} + hasBin: true + peerDependencies: + '@eslint-react/eslint-plugin': ^1.5.8 + '@prettier/plugin-xml': ^3.4.1 + '@unocss/eslint-plugin': '>=0.50.0' + astro-eslint-parser: ^1.0.2 + eslint: ^9.10.0 + eslint-plugin-astro: ^1.2.0 + eslint-plugin-format: '>=0.1.0' + eslint-plugin-react-hooks: ^5.0.0 + eslint-plugin-react-refresh: ^0.4.4 + eslint-plugin-solid: ^0.14.3 + eslint-plugin-svelte: '>=2.35.1' + prettier-plugin-astro: ^0.13.0 + prettier-plugin-slidev: ^1.0.5 + svelte-eslint-parser: '>=0.37.0' + peerDependenciesMeta: + '@eslint-react/eslint-plugin': + optional: true + '@prettier/plugin-xml': + optional: true + '@unocss/eslint-plugin': + optional: true + astro-eslint-parser: + optional: true + eslint-plugin-astro: + optional: true + eslint-plugin-format: + optional: true + eslint-plugin-react-hooks: + optional: true + eslint-plugin-react-refresh: + optional: true + eslint-plugin-solid: + optional: true + eslint-plugin-svelte: + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-slidev: + optional: true + svelte-eslint-parser: + optional: true + + '@antfu/install-pkg@0.4.1': + resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==} + + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + '@babel/code-frame@7.26.2': resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} @@ -203,6 +243,23 @@ packages: resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} + '@clack/core@0.3.4': + resolution: {integrity: sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==} + + '@clack/prompts@0.8.1': + resolution: {integrity: sha512-I263nEUNbX4lPTX93trl1fkIvGrGlz6nUYkqOddF0ZmjqcxUgUlXmpUIUqfapirRKJrFddvwF+qdZgg8cSqF7g==} + bundledDependencies: + - is-unicode-supported + + '@dprint/formatter@0.3.0': + resolution: {integrity: sha512-N9fxCxbaBOrDkteSOzaCqwWjso5iAe+WJPsHC021JfHNj2ThInPNEF13ORDKta3llq5D1TlclODCvOvipH7bWQ==} + + '@dprint/markdown@0.17.8': + resolution: {integrity: sha512-ukHFOg+RpG284aPdIg7iPrCYmMs3Dqy43S1ejybnwlJoFiW02b+6Bbr5cfZKFRYNP3dKGM86BqHEnMzBOyLvvA==} + + '@dprint/toml@0.6.3': + resolution: {integrity: sha512-zQ42I53sb4WVHA+5yoY1t59Zk++Ot02AvUgtNKLzTT8mPyVqVChFcePa3on/xIoKEgH+RoepgPHzqfk9837YFw==} + '@emotion/babel-plugin@11.12.0': resolution: {integrity: sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==} @@ -257,6 +314,14 @@ packages: '@emotion/weak-memoize@0.4.0': resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} + '@es-joy/jsdoccomment@0.48.0': + resolution: {integrity: sha512-G6QUWIcC+KvSwXNsJyDTHvqUdNoAVJPPgkc3+Uk4WBKqZvoXhlvazOgm9aL0HwihJLQf0l+tOE2UFzXBqCqgDw==} + engines: {node: '>=16'} + + '@es-joy/jsdoccomment@0.49.0': + resolution: {integrity: sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==} + engines: {node: '>=16'} + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -395,6 +460,12 @@ packages: cpu: [x64] os: [win32] + '@eslint-community/eslint-plugin-eslint-comments@4.4.1': + resolution: {integrity: sha512-lb/Z/MzbTf7CaVYM9WCFNQZ4L1yi3ev2fsFPF99h31ljhSEyUoyEsKsNWiU+qD1glbYTDJdqgyaLKtyTkkqtuQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + '@eslint-community/eslint-utils@4.4.1': resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -405,6 +476,37 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@eslint-react/ast@1.16.1': + resolution: {integrity: sha512-IzJnMy+70w8k1ek06vqdk8g/vxVffOII3c65ggtlQwj2ZBZB/cgUABzNkDV7Hi3VtE0kChZSVSDV6MR76gt5Sg==} + + '@eslint-react/core@1.16.1': + resolution: {integrity: sha512-QTuROazb1gILdV1h4iON38HbxQpOUMpEPg3etoFrLeH1a9yJIfnsb2t1ryrJh2pqQ+Rw5Lz6za+sJknbuDYxOg==} + + '@eslint-react/eslint-plugin@1.16.1': + resolution: {integrity: sha512-QTpBKDbe6DZCsczFkFjqVFRuwbUlMV+FF0XdZLrMRuHEvmcs/6G70wHL/hCe2CruARnGiAQRWnA+IenFw+gAuw==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + '@eslint-react/jsx@1.16.1': + resolution: {integrity: sha512-VrlCeVpRkAK5t8tpJRa+IOIdQQ9qTCnS1UOZOSV/SDcgBdsyGFkYzzY1EHUCR9MSxpsS/NPaXBfvrgMJ+llMow==} + + '@eslint-react/shared@1.16.1': + resolution: {integrity: sha512-A+R590q0UQuHVlz9YHs+g6HQZ/cyKK/bWw0ykyEAoTNXCDz8lpbxW02dH4iC/9eMEnYs2dQn4as1qkwm9GhrfQ==} + + '@eslint-react/tools@1.16.1': + resolution: {integrity: sha512-X/VbkpltsfLLM14SqAThFEEsvQOCopyFXRwnAJp6HU9SdZEy7CkqRdPz/EQl8w7SEl70/DVFI2kvx0FN8YP3bw==} + + '@eslint-react/types@1.16.1': + resolution: {integrity: sha512-0vNdbVtebCtlGZBFWmZaYvXYhgakKrvQz1WYeSmEMKLSebIgReSrvjqVOhQOvoz41lGIuNYUKfYVSWwj41lyDg==} + + '@eslint-react/var@1.16.1': + resolution: {integrity: sha512-CZ1fMQPkr60pwx8PLHsn75cl1Ovw/GHo2v6nhdWyhW8VhbBwJ1d1VdjSxPZjHJ4KCZFTuVVunWn7W9gDZmK+ow==} + '@eslint/compat@1.2.3': resolution: {integrity: sha512-wlZhwlDFxkxIZ571aH0FoK4h4Vwx7P3HJx62Gp8hTc10bfpwT2x0nULuAHmQSJBOWPgPeVf+9YtnD4j50zVHmA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -430,6 +532,10 @@ packages: resolution: {integrity: sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/markdown@6.2.1': + resolution: {integrity: sha512-cKVd110hG4ICHmWhIwZJfKmmJBvbiDWyrHODJknAtudKgZtlROGoLX9UEOA0o746zC0hCY4UV4vR+aOGW9S6JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/object-schema@2.1.4': resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -641,6 +747,10 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -747,6 +857,12 @@ packages: cpu: [x64] os: [win32] + '@stylistic/eslint-plugin@2.11.0': + resolution: {integrity: sha512-PNRHbydNG5EH8NK4c+izdJlxajIR6GxcUhzsYNRsn6Myep4dsZt0qFCz3rCPnkvgO5FYibDcMqgNHUT+zvjYZw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.40.0' + '@svgr/babel-plugin-add-jsx-attribute@8.0.0': resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} engines: {node: '>=14'} @@ -890,19 +1006,16 @@ packages: '@swc/types@0.1.15': resolution: {integrity: sha512-XKaZ+dzDIQ9Ot9o89oJQ/aluI17+VvUnIpYJTcZtvv1iYX6MzHh3Ik2CSR7MdPKpPwfZXHBeCingb2b4PoDVdw==} - '@tanstack/query-core@5.60.5': - resolution: {integrity: sha512-jiS1aC3XI3BJp83ZiTuDLerTmn9P3U95r6p+6/SNauLJaYxfIC4dMuWygwnBHIZxjn2zJqEpj3nysmPieoxfPQ==} + '@tanstack/query-core@5.60.6': + resolution: {integrity: sha512-tI+k0KyCo1EBJ54vxK1kY24LWj673ujTydCZmzEZKAew4NqZzTaVQJEuaG1qKj2M03kUHN46rchLRd+TxVq/zQ==} - '@tanstack/react-query@5.60.5': - resolution: {integrity: sha512-M77bOsPwj1wYE56gk7iJvxGAr4IC12NWdIDhT+Eo8ldkWRHMvIR8I/rufIvT1OXoV/bl7EECwuRuMlxxWtvW2Q==} + '@tanstack/react-query@5.60.6': + resolution: {integrity: sha512-FUzSDaiPkuZCmuGqrixfRRXJV9u+nrUh9lAlA5Q3ZFrOw1Js1VeBfxi1NIcJO3ZWJdKceBqKeBJdNcWStCYZnw==} peerDependencies: react: ^18 || ^19 - '@types/eslint@9.6.1': - resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} - - '@types/eslint__js@8.42.3': - resolution: {integrity: sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==} + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} @@ -916,9 +1029,18 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/ms@0.7.34': + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + '@types/node@22.9.0': resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==} + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -943,16 +1065,8 @@ packages: '@types/react@18.3.12': resolution: {integrity: sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==} - '@typescript-eslint/eslint-plugin@7.18.0': - resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} '@typescript-eslint/eslint-plugin@8.15.0': resolution: {integrity: sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg==} @@ -965,16 +1079,6 @@ packages: typescript: optional: true - '@typescript-eslint/parser@7.18.0': - resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/parser@8.15.0': resolution: {integrity: sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -985,24 +1089,10 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@7.18.0': - resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} - engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/scope-manager@8.15.0': resolution: {integrity: sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@7.18.0': - resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/type-utils@8.15.0': resolution: {integrity: sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1013,23 +1103,10 @@ packages: typescript: optional: true - '@typescript-eslint/types@7.18.0': - resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} - engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/types@8.15.0': resolution: {integrity: sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@7.18.0': - resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/typescript-estree@8.15.0': resolution: {integrity: sha512-1eMp2JgNec/niZsR7ioFBlsh/Fk0oJbhaqO0jRyQBMgkz7RrFfkqF9lYYmBoGBaSiLnu8TAPQTwoTUiSTUW9dg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1039,12 +1116,6 @@ packages: typescript: optional: true - '@typescript-eslint/utils@7.18.0': - resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - '@typescript-eslint/utils@8.15.0': resolution: {integrity: sha512-k82RI9yGhr0QM3Dnq+egEpz9qB6Un+WLYhmoNcvl8ltMEededhh7otBVVIDDsEEttauwdY/hQoSsOv13lxrFzQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1055,10 +1126,6 @@ packages: typescript: optional: true - '@typescript-eslint/visitor-keys@7.18.0': - resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} - engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/visitor-keys@8.15.0': resolution: {integrity: sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1068,6 +1135,34 @@ packages: peerDependencies: vite: ^4 || ^5 + '@vitest/eslint-plugin@1.1.10': + resolution: {integrity: sha512-uScH5Kz5v32vvtQYB2iodpoPg2mGASK+VKpjlc2IUgE0+16uZKqVKi2vQxjxJ6sMCQLBs4xhBFZlmZBszsmfKQ==} + peerDependencies: + '@typescript-eslint/utils': '>= 8.0' + eslint: '>= 8.57.0' + typescript: '>= 5.0.0' + vitest: '*' + peerDependenciesMeta: + typescript: + optional: true + vitest: + optional: true + + '@vue/compiler-core@3.5.13': + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + + '@vue/compiler-dom@3.5.13': + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + + '@vue/compiler-sfc@3.5.13': + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + + '@vue/compiler-ssr@3.5.13': + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + + '@vue/shared@3.5.13': + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + '@yr/monotone-cubic-spline@1.0.3': resolution: {integrity: sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==} @@ -1084,6 +1179,10 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -1091,13 +1190,13 @@ packages: apexcharts@3.54.1: resolution: {integrity: sha512-E4et0h/J1U3r3EwS/WlqJCQIbepKbp6wGUmaAwJOMjHUP4Ci0gxanLa7FR3okx6p9coi4st6J853/Cb1NP0vpA==} + are-docs-informative@0.0.2: + resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} + engines: {node: '>=14'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - babel-plugin-macros@3.1.0: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} @@ -1105,6 +1204,12 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + birecord@0.1.1: + resolution: {integrity: sha512-VUpsf/qykW0heRlC8LooCq28Kxn3mAqKohhDG/49rrsQ1dT1CXyj/pgXS+5BSRzFTR/3DyIBOqQOrGyZOh71Aw==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -1135,13 +1240,31 @@ packages: caniuse-lite@1.0.30001680: resolution: {integrity: sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==} + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + ci-info@4.1.0: + resolution: {integrity: sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==} + engines: {node: '>=8'} + classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + clsx@1.2.1: resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} engines: {node: '>=6'} @@ -1157,15 +1280,25 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + core-js-compat@3.39.0: + resolution: {integrity: sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==} + cosmiconfig@7.1.0: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} @@ -1183,12 +1316,25 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.3.7: resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} @@ -1198,12 +1344,22 @@ packages: supports-color: optional: true + decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} @@ -1214,6 +1370,13 @@ packages: electron-to-chromium@1.5.63: resolution: {integrity: sha512-ddeXKuY9BHo/mw145axlyWjlJ1UBt4WK3AlvkT7W2AbqfRQoacVoRUCF6wL3uIx/8wT9oLKXzI+rFqHHscByaA==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + enhanced-resolve@5.17.1: + resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + engines: {node: '>=10.13.0'} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -1221,6 +1384,9 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -1230,19 +1396,21 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-config-prettier@9.1.0: - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} - eslint-plugin-react-hooks@4.6.2: - resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} - engines: {node: '>=10'} + eslint-compat-utils@0.5.1: + resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} + engines: {node: '>=12'} peerDependencies: eslint: '>=6.0.0' @@ -1406,6 +1574,75 @@ packages: peerDependencies: eslint: '>=7' + eslint-plugin-react-web-api@1.16.1: + resolution: {integrity: sha512-kQp8NlJESf87tVPyQnzyziVUwbqYhn0Xsrwj8joA8Bxnkt2bsylmDuMoBV0VntNYnfgoUvBj8D/OuZgb1IfLVQ==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + eslint-plugin-react-x@1.16.1: + resolution: {integrity: sha512-Oqu3DMLHXEisvXrAzk7lyZ57W6MlP8nOo3/PkcKtxImB5fCGYILKJY22Jz6hfWZ3MhTzEuVZru8x26Mev+9thQ==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + eslint-plugin-regexp@2.7.0: + resolution: {integrity: sha512-U8oZI77SBtH8U3ulZ05iu0qEzIizyEDXd+BWHvyVxTOjGwcDcvy/kEpgFG4DYca2ByRLiVPFZ2GeH7j1pdvZTA==} + engines: {node: ^18 || >=20} + peerDependencies: + eslint: '>=8.44.0' + + eslint-plugin-toml@0.11.1: + resolution: {integrity: sha512-Y1WuMSzfZpeMIrmlP1nUh3kT8p96mThIq4NnHrYUhg10IKQgGfBZjAWnrg9fBqguiX4iFps/x/3Hb5TxBisfdw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + eslint-plugin-unicorn@56.0.1: + resolution: {integrity: sha512-FwVV0Uwf8XPfVnKSGpMg7NtlZh0G0gBarCaFcMUOoqPxXryxdYxTRRv4kH6B9TFCVIrjRXG+emcxIk2ayZilog==} + engines: {node: '>=18.18'} + peerDependencies: + eslint: '>=8.56.0' + + eslint-plugin-unused-imports@4.1.4: + resolution: {integrity: sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 + eslint: ^9.0.0 || ^8.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + + eslint-plugin-vue@9.31.0: + resolution: {integrity: sha512-aYMUCgivhz1o4tLkRHj5oq9YgYPM4/EJc0M7TAKRLCUA5OYxRLAhYEVD2nLtTwLyixEFI+/QXSvKU9ESZFgqjQ==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-plugin-yml@1.15.0: + resolution: {integrity: sha512-leC8APYVOsKyWUlvRwVhewytK5wS70BfMqIaUplFstRfzCoVp0YoEroV4cUEvQrBj93tQ3M9LcjO/ewr6D4kjA==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + eslint-processor-vue-blocks@0.1.2: + resolution: {integrity: sha512-PfpJ4uKHnqeL/fXUnzYkOax3aIenlwewXRX8jFinA1a2yCFnLgMuiH3xvCgvHHUlV2xJWQHbCTdiJWGwb3NqpQ==} + peerDependencies: + '@vue/compiler-sfc': ^3.3.0 + eslint: ^8.50.0 || ^9.0.0 + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@8.2.0: resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1432,6 +1669,10 @@ packages: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -1454,6 +1695,9 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -1478,6 +1722,14 @@ packages: find-root@1.1.0: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + find-up-simple@1.0.0: + resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==} + engines: {node: '>=18'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -1501,6 +1753,13 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1513,13 +1772,17 @@ packages: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + globals@15.12.0: + resolution: {integrity: sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==} + engines: {node: '>=18'} goober@2.1.16: resolution: {integrity: sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==} @@ -1543,6 +1806,9 @@ packages: hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1555,9 +1821,17 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + is-core-module@2.15.1: resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} @@ -1566,10 +1840,20 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-immutable-type@5.0.0: + resolution: {integrity: sha512-mcvHasqbRBWJznuPqqHRKiJgYAz60sZ0mvO3bN70JbkuK7ksfmgc489aKZYxMEjIbRvyOseaTjaRZLRF/xFeRA==} + peerDependencies: + eslint: '*' + typescript: '>=4.7.4' + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -1588,6 +1872,14 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + jsdoc-type-pratt-parser@4.1.0: + resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} + engines: {node: '>=12.0.0'} + + jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + jsesc@3.0.2: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} engines: {node: '>=6'} @@ -1624,6 +1916,14 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -1631,6 +1931,12 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -1641,6 +1947,12 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + magic-string@0.30.13: + resolution: {integrity: sha512-8rYBO+MsWkgjDSOvLomYnzhdwEG51olQ4zL5KXnNJWV5MNmrb4rTZdrtkhxjnD/QyZUqR/Z/XDsUs/4ej2nx0g==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + material-ui-confirm@3.0.16: resolution: {integrity: sha512-aJoa/FM/U/86qztoljlk8FWmjSJbAMzDWCdWbDqU5WwB0WzcWPyGrhBvIqihR9uKdHKBf1YrvMjn68uOrfsXAg==} peerDependencies: @@ -1691,23 +2003,118 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + micromark-core-commonmark@2.0.2: + resolution: {integrity: sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + micromark-extension-gfm-table@2.1.0: + resolution: {integrity: sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.0.2: + resolution: {integrity: sha512-xKxhkB62vwHUuuxHe9Xqty3UaAsizV2YKq5OV344u3hFBbf8zIYrhYOWhAQb94MtMPkjTOzzjJ/hid9/dR5vFA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.1: + resolution: {integrity: sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==} + + micromark@4.0.1: + resolution: {integrity: sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + mlly@1.7.3: + resolution: {integrity: sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true natural-compare-lite@1.4.0: @@ -1722,6 +2129,9 @@ packages: node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + notistack@3.0.1: resolution: {integrity: sha512-ntVZXXgSQH5WYfyU+3HfcXuKaapzAJ8fBLQ/G618rn3yvSzEbnOB8ZSOwhX+dAORy/lw+GC2N061JA0+gYWTVA==} engines: {node: '>=12.0.0', npm: '>=6.0.0'} @@ -1740,18 +2150,41 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-manager-detector@0.2.4: + resolution: {integrity: sha512-H/OUu9/zUfP89z1APcBf2X8Us0tt8dUK4lUmKqz12QNXif3DxAs1/YqjGtcutZi1zQqeNQRWr9C+EbQnnvSSFA==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-gitignore@2.0.0: + resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==} + engines: {node: '>=14'} + + parse-imports@2.2.1: + resolution: {integrity: sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==} + engines: {node: '>= 18'} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -1771,6 +2204,9 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1782,6 +2218,17 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} + pkg-types@1.2.1: + resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + postcss@8.4.49: resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} engines: {node: ^10 || ^12 || >=14} @@ -1790,6 +2237,10 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + prettier@3.3.3: resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} @@ -1857,13 +2308,44 @@ packages: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} + read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + + read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + + refa@0.12.1: + resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + regexp-ast-analysis@0.7.1: + resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + + regjsparser@0.10.0: + resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} + hasBin: true + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -1883,6 +2365,14 @@ packages: scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scslre@0.3.0: + resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} + engines: {node: ^14.0.0 || >=16.0.0} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -1900,9 +2390,15 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} + short-unique-id@5.2.0: + resolution: {integrity: sha512-cMGfwNyfDZ/nzJ2k2M+ClthBIh//GlZl1JEf47Uoa9XR11bz8Pa2T2wQO4bVrRdH48LrIDWJahQziKo3MjhsWg==} + hasBin: true + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slashes@3.0.12: + resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==} snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} @@ -1915,6 +2411,39 @@ packages: resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} engines: {node: '>=0.10.0'} + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-expression-parse@4.0.0: + resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} + + spdx-license-ids@3.0.20: + resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} + + stable-hash@0.0.4: + resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==} + + string-ts@2.2.0: + resolution: {integrity: sha512-VTP0LLZo4Jp9Gz5IiDVMS9WyLx/3IeYh0PXUn0NdPqusUFNgkHPWiEdbB9TU2Iv3myUskraD5WtYEdHUrQEIlQ==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -1964,16 +2493,43 @@ packages: resolution: {integrity: sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==} engines: {node: '>= 0.8.0'} + synckit@0.6.2: + resolution: {integrity: sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==} + engines: {node: '>=12.20'} + + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} + engines: {node: ^14.18.0 || >=16.0.0} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toml-eslint-parser@0.10.0: + resolution: {integrity: sha512-khrZo4buq4qVmsGzS5yQjKe/WsFvV8fGfOjDQN0q4iy9FjRfPWRgTFrU8u1R2iu/SfWLhY9WnCi4Jhdrcbtg+g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + ts-api-utils@1.4.0: resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' + ts-declaration-location@1.0.4: + resolution: {integrity: sha512-r4JoxYhKULbZuH81Pjrp9OEG5St7XWk7zXwGkLKhmVcjiBVHTJXV5wK6dEa9JKW5QGSTW6b1lOjxAKp8R1SQhg==} + peerDependencies: + typescript: '>=4.0.0' + + ts-pattern@5.5.0: + resolution: {integrity: sha512-jqbIpTsa/KKTJYWgPNsFNbLVpwCgzXfFJ1ukNn4I8hMwyQzHMJnk/BqWzggB0xpkILuKzaO/aMYhS0SkaJyKXg==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -1981,6 +2537,18 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + + type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + typescript-eslint@8.15.0: resolution: {integrity: sha512-wY4FRGl0ZI+ZU4Jo/yjdBu0lVTSML58pu6PgGtJmCufvzfV565pUF6iACQt092uFOd49iLOTX/sEVmHtbSrS+w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2002,6 +2570,18 @@ packages: undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + update-browserslist-db@1.1.1: resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true @@ -2011,6 +2591,12 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vite-plugin-svgr@4.3.0: resolution: {integrity: sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==} peerDependencies: @@ -2062,17 +2648,49 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yaml-eslint-parser@1.2.3: + resolution: {integrity: sha512-4wZWvE398hCP7O8n3nXKu/vdq1HcH01ixYlCREaJL5NUMwQ0g3MaGFUBNSlmBtKmhbtVG/Cm6lyYmSVTEVil8A==} + engines: {node: ^14.17.0 || >=16.0.0} + yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} + yaml@2.6.1: + resolution: {integrity: sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==} + engines: {node: '>= 14'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: '@ampproject/remapping@2.3.0': @@ -2080,6 +2698,65 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 + '@antfu/eslint-config@3.9.2(@eslint-react/eslint-plugin@1.16.1(eslint@9.15.0)(typescript@5.6.3))(@typescript-eslint/utils@8.15.0(eslint@9.15.0)(typescript@5.6.3))(@vue/compiler-sfc@3.5.13)(eslint-plugin-format@0.1.2(eslint@9.15.0))(eslint-plugin-react-hooks@5.1.0-beta-26f2496093-20240514(eslint@9.15.0))(eslint-plugin-react-refresh@0.4.14(eslint@9.15.0))(eslint@9.15.0)(typescript@5.6.3)': + dependencies: + '@antfu/install-pkg': 0.4.1 + '@clack/prompts': 0.8.1 + '@eslint-community/eslint-plugin-eslint-comments': 4.4.1(eslint@9.15.0) + '@eslint/markdown': 6.2.1 + '@stylistic/eslint-plugin': 2.11.0(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/eslint-plugin': 8.15.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/parser': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + '@vitest/eslint-plugin': 1.1.10(@typescript-eslint/utils@8.15.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3) + eslint: 9.15.0 + eslint-config-flat-gitignore: 0.3.0(eslint@9.15.0) + eslint-flat-config-utils: 0.4.0 + eslint-merge-processors: 0.1.0(eslint@9.15.0) + eslint-plugin-antfu: 2.7.0(eslint@9.15.0) + eslint-plugin-command: 0.2.6(eslint@9.15.0) + eslint-plugin-import-x: 4.4.2(eslint@9.15.0)(typescript@5.6.3) + eslint-plugin-jsdoc: 50.5.0(eslint@9.15.0) + eslint-plugin-jsonc: 2.18.2(eslint@9.15.0) + eslint-plugin-n: 17.13.2(eslint@9.15.0) + eslint-plugin-no-only-tests: 3.3.0 + eslint-plugin-perfectionist: 3.9.1(eslint@9.15.0)(typescript@5.6.3)(vue-eslint-parser@9.4.3(eslint@9.15.0)) + eslint-plugin-regexp: 2.7.0(eslint@9.15.0) + eslint-plugin-toml: 0.11.1(eslint@9.15.0) + eslint-plugin-unicorn: 56.0.1(eslint@9.15.0) + eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0) + eslint-plugin-vue: 9.31.0(eslint@9.15.0) + eslint-plugin-yml: 1.15.0(eslint@9.15.0) + eslint-processor-vue-blocks: 0.1.2(@vue/compiler-sfc@3.5.13)(eslint@9.15.0) + globals: 15.12.0 + jsonc-eslint-parser: 2.4.0 + local-pkg: 0.5.1 + parse-gitignore: 2.0.0 + picocolors: 1.1.1 + toml-eslint-parser: 0.10.0 + vue-eslint-parser: 9.4.3(eslint@9.15.0) + yaml-eslint-parser: 1.2.3 + yargs: 17.7.2 + optionalDependencies: + '@eslint-react/eslint-plugin': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + eslint-plugin-format: 0.1.2(eslint@9.15.0) + eslint-plugin-react-hooks: 5.1.0-beta-26f2496093-20240514(eslint@9.15.0) + eslint-plugin-react-refresh: 0.4.14(eslint@9.15.0) + transitivePeerDependencies: + - '@eslint/json' + - '@typescript-eslint/utils' + - '@vue/compiler-sfc' + - supports-color + - svelte + - typescript + - vitest + + '@antfu/install-pkg@0.4.1': + dependencies: + package-manager-detector: 0.2.4 + tinyexec: 0.3.1 + + '@antfu/utils@0.7.10': {} + '@babel/code-frame@7.26.2': dependencies: '@babel/helper-validator-identifier': 7.25.9 @@ -2182,6 +2859,23 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@clack/core@0.3.4': + dependencies: + picocolors: 1.1.1 + sisteransi: 1.0.5 + + '@clack/prompts@0.8.1': + dependencies: + '@clack/core': 0.3.4 + picocolors: 1.1.1 + sisteransi: 1.0.5 + + '@dprint/formatter@0.3.0': {} + + '@dprint/markdown@0.17.8': {} + + '@dprint/toml@0.6.3': {} + '@emotion/babel-plugin@11.12.0': dependencies: '@babel/helper-module-imports': 7.25.9 @@ -2265,6 +2959,18 @@ snapshots: '@emotion/weak-memoize@0.4.0': {} + '@es-joy/jsdoccomment@0.48.0': + dependencies: + comment-parser: 1.4.1 + esquery: 1.6.0 + jsdoc-type-pratt-parser: 4.1.0 + + '@es-joy/jsdoccomment@0.49.0': + dependencies: + comment-parser: 1.4.1 + esquery: 1.6.0 + jsdoc-type-pratt-parser: 4.1.0 + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -2334,6 +3040,12 @@ snapshots: '@esbuild/win32-x64@0.21.5': optional: true + '@eslint-community/eslint-plugin-eslint-comments@4.4.1(eslint@9.15.0)': + dependencies: + escape-string-regexp: 4.0.0 + eslint: 9.15.0 + ignore: 5.3.2 + '@eslint-community/eslint-utils@4.4.1(eslint@9.15.0)': dependencies: eslint: 9.15.0 @@ -2341,6 +3053,113 @@ snapshots: '@eslint-community/regexpp@4.12.1': {} + '@eslint-react/ast@1.16.1(eslint@9.15.0)(typescript@5.6.3)': + dependencies: + '@eslint-react/tools': 1.16.1 + '@eslint-react/types': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3) + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + birecord: 0.1.1 + string-ts: 2.2.0 + ts-pattern: 5.5.0 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@eslint-react/core@1.16.1(eslint@9.15.0)(typescript@5.6.3)': + dependencies: + '@eslint-react/ast': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/jsx': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/shared': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/tools': 1.16.1 + '@eslint-react/types': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/var': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.15.0 + '@typescript-eslint/type-utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + birecord: 0.1.1 + short-unique-id: 5.2.0 + ts-pattern: 5.5.0 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@eslint-react/eslint-plugin@1.16.1(eslint@9.15.0)(typescript@5.6.3)': + dependencies: + '@eslint-react/shared': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/tools': 1.16.1 + '@eslint-react/types': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.15.0 + '@typescript-eslint/type-utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + eslint: 9.15.0 + eslint-plugin-react-debug: 1.16.1(eslint@9.15.0)(typescript@5.6.3) + eslint-plugin-react-dom: 1.16.1(eslint@9.15.0)(typescript@5.6.3) + eslint-plugin-react-hooks-extra: 1.16.1(eslint@9.15.0)(typescript@5.6.3) + eslint-plugin-react-naming-convention: 1.16.1(eslint@9.15.0)(typescript@5.6.3) + eslint-plugin-react-web-api: 1.16.1(eslint@9.15.0)(typescript@5.6.3) + eslint-plugin-react-x: 1.16.1(eslint@9.15.0)(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@eslint-react/jsx@1.16.1(eslint@9.15.0)(typescript@5.6.3)': + dependencies: + '@eslint-react/ast': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/tools': 1.16.1 + '@eslint-react/types': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/var': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.15.0 + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + ts-pattern: 5.5.0 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@eslint-react/shared@1.16.1(eslint@9.15.0)(typescript@5.6.3)': + dependencies: + '@eslint-react/tools': 1.16.1 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + picomatch: 4.0.2 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@eslint-react/tools@1.16.1': {} + + '@eslint-react/types@1.16.1(eslint@9.15.0)(typescript@5.6.3)': + dependencies: + '@eslint-react/tools': 1.16.1 + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@eslint-react/var@1.16.1(eslint@9.15.0)(typescript@5.6.3)': + dependencies: + '@eslint-react/ast': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/tools': 1.16.1 + '@eslint-react/types': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.15.0 + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + ts-pattern: 5.5.0 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + '@eslint/compat@1.2.3(eslint@9.15.0)': optionalDependencies: eslint: 9.15.0 @@ -2371,6 +3190,15 @@ snapshots: '@eslint/js@9.15.0': {} + '@eslint/markdown@6.2.1': + dependencies: + '@eslint/plugin-kit': 0.2.3 + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm: 3.0.0 + micromark-extension-gfm: 3.0.0 + transitivePeerDependencies: + - supports-color + '@eslint/object-schema@2.1.4': {} '@eslint/plugin-kit@0.2.3': @@ -2555,6 +3383,8 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@pkgr/core@0.1.1': {} + '@popperjs/core@2.11.8': {} '@remix-run/router@1.21.0': {} @@ -2621,6 +3451,18 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.27.3': optional: true + '@stylistic/eslint-plugin@2.11.0(eslint@9.15.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + eslint: 9.15.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + estraverse: 5.3.0 + picomatch: 4.0.2 + transitivePeerDependencies: + - supports-color + - typescript + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -2743,21 +3585,16 @@ snapshots: dependencies: '@swc/counter': 0.1.3 - '@tanstack/query-core@5.60.5': {} + '@tanstack/query-core@5.60.6': {} - '@tanstack/react-query@5.60.5(react@18.3.1)': + '@tanstack/react-query@5.60.6(react@18.3.1)': dependencies: - '@tanstack/query-core': 5.60.5 + '@tanstack/query-core': 5.60.6 react: 18.3.1 - '@types/eslint@9.6.1': - dependencies: - '@types/estree': 1.0.6 - '@types/json-schema': 7.0.15 - - '@types/eslint__js@8.42.3': + '@types/debug@4.1.12': dependencies: - '@types/eslint': 9.6.1 + '@types/ms': 0.7.34 '@types/estree@1.0.6': {} @@ -2767,10 +3604,18 @@ snapshots: '@types/json-schema@7.0.15': {} + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/ms@0.7.34': {} + '@types/node@22.9.0': dependencies: undici-types: 6.19.8 + '@types/normalize-package-data@2.4.4': {} + '@types/parse-json@4.0.2': {} '@types/prop-types@15.7.13': {} @@ -2805,23 +3650,7 @@ snapshots: '@types/prop-types': 15.7.13 csstype: 3.1.3 - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 7.18.0(eslint@9.15.0)(typescript@5.6.3) - '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@9.15.0)(typescript@5.6.3) - '@typescript-eslint/utils': 7.18.0(eslint@9.15.0)(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 7.18.0 - eslint: 9.15.0 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare: 1.4.0 - ts-api-utils: 1.4.0(typescript@5.6.3) - optionalDependencies: - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color + '@types/unist@3.0.3': {} '@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3)': dependencies: @@ -2841,19 +3670,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@9.15.0)(typescript@5.6.3)': - dependencies: - '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.3.7 - eslint: 9.15.0 - optionalDependencies: - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/parser@8.15.0(eslint@9.15.0)(typescript@5.6.3)': dependencies: '@typescript-eslint/scope-manager': 8.15.0 @@ -2867,28 +3683,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@7.18.0': - dependencies: - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/visitor-keys': 7.18.0 - '@typescript-eslint/scope-manager@8.15.0': dependencies: '@typescript-eslint/types': 8.15.0 '@typescript-eslint/visitor-keys': 8.15.0 - '@typescript-eslint/type-utils@7.18.0(eslint@9.15.0)(typescript@5.6.3)': - dependencies: - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) - '@typescript-eslint/utils': 7.18.0(eslint@9.15.0)(typescript@5.6.3) - debug: 4.3.7 - eslint: 9.15.0 - ts-api-utils: 1.4.0(typescript@5.6.3) - optionalDependencies: - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/type-utils@8.15.0(eslint@9.15.0)(typescript@5.6.3)': dependencies: '@typescript-eslint/typescript-estree': 8.15.0(typescript@5.6.3) @@ -2901,25 +3700,8 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@7.18.0': {} - '@typescript-eslint/types@8.15.0': {} - '@typescript-eslint/typescript-estree@7.18.0(typescript@5.6.3)': - dependencies: - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.3.7 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.6.3 - ts-api-utils: 1.4.0(typescript@5.6.3) - optionalDependencies: - typescript: 5.6.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/typescript-estree@8.15.0(typescript@5.6.3)': dependencies: '@typescript-eslint/types': 8.15.0 @@ -2935,16 +3717,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.18.0(eslint@9.15.0)(typescript@5.6.3)': - dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) - '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.3) - eslint: 9.15.0 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/utils@8.15.0(eslint@9.15.0)(typescript@5.6.3)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) @@ -2957,22 +3729,56 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@7.18.0': + '@typescript-eslint/visitor-keys@8.15.0': dependencies: - '@typescript-eslint/types': 7.18.0 - eslint-visitor-keys: 3.4.3 + '@typescript-eslint/types': 8.15.0 + eslint-visitor-keys: 4.2.0 + + '@vitejs/plugin-react-swc@3.7.1(vite@5.4.11(@types/node@22.9.0))': + dependencies: + '@swc/core': 1.9.2 + vite: 5.4.11(@types/node@22.9.0) + transitivePeerDependencies: + - '@swc/helpers' + + '@vitest/eslint-plugin@1.1.10(@typescript-eslint/utils@8.15.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + eslint: 9.15.0 + optionalDependencies: + typescript: 5.6.3 + + '@vue/compiler-core@3.5.13': + dependencies: + '@babel/parser': 7.26.2 + '@vue/shared': 3.5.13 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.13': + dependencies: + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/compiler-sfc@3.5.13': + dependencies: + '@babel/parser': 7.26.2 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + estree-walker: 2.0.2 + magic-string: 0.30.13 + postcss: 8.4.49 + source-map-js: 1.2.1 - '@typescript-eslint/visitor-keys@8.15.0': + '@vue/compiler-ssr@3.5.13': dependencies: - '@typescript-eslint/types': 8.15.0 - eslint-visitor-keys: 4.2.0 + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 - '@vitejs/plugin-react-swc@3.7.1(vite@5.4.11(@types/node@22.9.0))': - dependencies: - '@swc/core': 1.9.2 - vite: 5.4.11(@types/node@22.9.0) - transitivePeerDependencies: - - '@swc/helpers' + '@vue/shared@3.5.13': {} '@yr/monotone-cubic-spline@1.0.3': {} @@ -3049,6 +3855,8 @@ snapshots: caniuse-lite@1.0.30001680: {} + ccount@2.0.1: {} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -3159,6 +3967,13 @@ snapshots: electron-to-chromium@1.5.63: {} + emoji-regex@8.0.0: {} + + enhanced-resolve@5.17.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + entities@4.5.0: {} error-ex@1.3.2: @@ -3199,18 +4014,366 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@9.1.0(eslint@9.15.0): + escape-string-regexp@5.0.0: {} + + eslint-compat-utils@0.5.1(eslint@9.15.0): + dependencies: + eslint: 9.15.0 + semver: 7.6.3 + + eslint-compat-utils@0.6.3(eslint@9.15.0): + dependencies: + eslint: 9.15.0 + semver: 7.6.3 + + eslint-config-flat-gitignore@0.3.0(eslint@9.15.0): + dependencies: + '@eslint/compat': 1.2.3(eslint@9.15.0) + eslint: 9.15.0 + find-up-simple: 1.0.0 + + eslint-flat-config-utils@0.4.0: + dependencies: + pathe: 1.1.2 + + eslint-formatting-reporter@0.0.0(eslint@9.15.0): + dependencies: + eslint: 9.15.0 + prettier-linter-helpers: 1.0.0 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.15.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-json-compat-utils@0.2.1(eslint@9.15.0)(jsonc-eslint-parser@2.4.0): + dependencies: + eslint: 9.15.0 + esquery: 1.6.0 + jsonc-eslint-parser: 2.4.0 + + eslint-merge-processors@0.1.0(eslint@9.15.0): + dependencies: + eslint: 9.15.0 + + eslint-parser-plain@0.1.0: {} + + eslint-plugin-antfu@2.7.0(eslint@9.15.0): + dependencies: + '@antfu/utils': 0.7.10 + eslint: 9.15.0 + + eslint-plugin-command@0.2.6(eslint@9.15.0): + dependencies: + '@es-joy/jsdoccomment': 0.48.0 + eslint: 9.15.0 + + eslint-plugin-es-x@7.8.0(eslint@9.15.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) + '@eslint-community/regexpp': 4.12.1 + eslint: 9.15.0 + eslint-compat-utils: 0.5.1(eslint@9.15.0) + + eslint-plugin-format@0.1.2(eslint@9.15.0): + dependencies: + '@dprint/formatter': 0.3.0 + '@dprint/markdown': 0.17.8 + '@dprint/toml': 0.6.3 + eslint: 9.15.0 + eslint-formatting-reporter: 0.0.0(eslint@9.15.0) + eslint-parser-plain: 0.1.0 + prettier: 3.3.3 + synckit: 0.9.2 + + eslint-plugin-import-x@4.4.2(eslint@9.15.0)(typescript@5.6.3): + dependencies: + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + debug: 4.3.7 + doctrine: 3.0.0 + eslint: 9.15.0 + eslint-import-resolver-node: 0.3.9 + get-tsconfig: 4.8.1 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + stable-hash: 0.0.4 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-jsdoc@50.5.0(eslint@9.15.0): + dependencies: + '@es-joy/jsdoccomment': 0.49.0 + are-docs-informative: 0.0.2 + comment-parser: 1.4.1 + debug: 4.3.7 + escape-string-regexp: 4.0.0 + eslint: 9.15.0 + espree: 10.3.0 + esquery: 1.6.0 + parse-imports: 2.2.1 + semver: 7.6.3 + spdx-expression-parse: 4.0.0 + synckit: 0.9.2 + transitivePeerDependencies: + - supports-color + + eslint-plugin-jsonc@2.18.2(eslint@9.15.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) + eslint: 9.15.0 + eslint-compat-utils: 0.6.3(eslint@9.15.0) + eslint-json-compat-utils: 0.2.1(eslint@9.15.0)(jsonc-eslint-parser@2.4.0) + espree: 9.6.1 + graphemer: 1.4.0 + jsonc-eslint-parser: 2.4.0 + natural-compare: 1.4.0 + synckit: 0.6.2 + transitivePeerDependencies: + - '@eslint/json' + + eslint-plugin-n@17.13.2(eslint@9.15.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) + enhanced-resolve: 5.17.1 + eslint: 9.15.0 + eslint-plugin-es-x: 7.8.0(eslint@9.15.0) + get-tsconfig: 4.8.1 + globals: 15.12.0 + ignore: 5.3.2 + minimatch: 9.0.5 + semver: 7.6.3 + + eslint-plugin-no-only-tests@3.3.0: {} + + eslint-plugin-perfectionist@3.9.1(eslint@9.15.0)(typescript@5.6.3)(vue-eslint-parser@9.4.3(eslint@9.15.0)): + dependencies: + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + eslint: 9.15.0 + minimatch: 9.0.5 + natural-compare-lite: 1.4.0 + optionalDependencies: + vue-eslint-parser: 9.4.3(eslint@9.15.0) + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-react-debug@1.16.1(eslint@9.15.0)(typescript@5.6.3): + dependencies: + '@eslint-react/ast': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/core': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/jsx': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/shared': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/tools': 1.16.1 + '@eslint-react/types': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/var': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.15.0 + '@typescript-eslint/type-utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + eslint: 9.15.0 + string-ts: 2.2.0 + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-dom@1.16.1(eslint@9.15.0)(typescript@5.6.3): + dependencies: + '@eslint-react/ast': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/core': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/jsx': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/shared': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/tools': 1.16.1 + '@eslint-react/types': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/var': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.15.0 + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + eslint: 9.15.0 + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-hooks-extra@1.16.1(eslint@9.15.0)(typescript@5.6.3): + dependencies: + '@eslint-react/ast': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/core': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/jsx': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/shared': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/tools': 1.16.1 + '@eslint-react/types': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/var': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.15.0 + '@typescript-eslint/type-utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + eslint: 9.15.0 + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-hooks@5.1.0-beta-26f2496093-20240514(eslint@9.15.0): dependencies: eslint: 9.15.0 - eslint-plugin-react-hooks@4.6.2(eslint@9.15.0): + eslint-plugin-react-naming-convention@1.16.1(eslint@9.15.0)(typescript@5.6.3): dependencies: + '@eslint-react/ast': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/core': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/jsx': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/shared': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/tools': 1.16.1 + '@eslint-react/types': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.15.0 + '@typescript-eslint/type-utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) eslint: 9.15.0 + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color eslint-plugin-react-refresh@0.4.14(eslint@9.15.0): dependencies: eslint: 9.15.0 + eslint-plugin-react-web-api@1.16.1(eslint@9.15.0)(typescript@5.6.3): + dependencies: + '@eslint-react/ast': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/core': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/jsx': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/shared': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/tools': 1.16.1 + '@eslint-react/types': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/var': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.15.0 + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + birecord: 0.1.1 + eslint: 9.15.0 + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-x@1.16.1(eslint@9.15.0)(typescript@5.6.3): + dependencies: + '@eslint-react/ast': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/core': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/jsx': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/shared': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/tools': 1.16.1 + '@eslint-react/types': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@eslint-react/var': 1.16.1(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.15.0 + '@typescript-eslint/type-utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + '@typescript-eslint/types': 8.15.0 + '@typescript-eslint/utils': 8.15.0(eslint@9.15.0)(typescript@5.6.3) + eslint: 9.15.0 + is-immutable-type: 5.0.0(eslint@9.15.0)(typescript@5.6.3) + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + eslint-plugin-regexp@2.7.0(eslint@9.15.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) + '@eslint-community/regexpp': 4.12.1 + comment-parser: 1.4.1 + eslint: 9.15.0 + jsdoc-type-pratt-parser: 4.1.0 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + scslre: 0.3.0 + + eslint-plugin-toml@0.11.1(eslint@9.15.0): + dependencies: + debug: 4.3.7 + eslint: 9.15.0 + eslint-compat-utils: 0.5.1(eslint@9.15.0) + lodash: 4.17.21 + toml-eslint-parser: 0.10.0 + transitivePeerDependencies: + - supports-color + + eslint-plugin-unicorn@56.0.1(eslint@9.15.0): + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) + ci-info: 4.1.0 + clean-regexp: 1.0.0 + core-js-compat: 3.39.0 + eslint: 9.15.0 + esquery: 1.6.0 + globals: 15.12.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.10.0 + semver: 7.6.3 + strip-indent: 3.0.0 + + eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0): + dependencies: + eslint: 9.15.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 8.15.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3) + + eslint-plugin-vue@9.31.0(eslint@9.15.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) + eslint: 9.15.0 + globals: 13.24.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.2 + semver: 7.6.3 + vue-eslint-parser: 9.4.3(eslint@9.15.0) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + + eslint-plugin-yml@1.15.0(eslint@9.15.0): + dependencies: + debug: 4.3.7 + eslint: 9.15.0 + eslint-compat-utils: 0.5.1(eslint@9.15.0) + lodash: 4.17.21 + natural-compare: 1.4.0 + yaml-eslint-parser: 1.2.3 + transitivePeerDependencies: + - supports-color + + eslint-processor-vue-blocks@0.1.2(@vue/compiler-sfc@3.5.13)(eslint@9.15.0): + dependencies: + '@vue/compiler-sfc': 3.5.13 + eslint: 9.15.0 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-scope@8.2.0: dependencies: esrecurse: 4.3.0 @@ -3265,6 +4428,12 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.14.0) eslint-visitor-keys: 4.2.0 + espree@9.6.1: + dependencies: + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 3.4.3 + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -3933,6 +5102,19 @@ snapshots: picomatch@4.0.2: {} + pkg-types@1.2.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.3 + pathe: 1.1.2 + + pluralize@8.0.0: {} + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + postcss@8.4.49: dependencies: nanoid: 3.3.7 @@ -4105,7 +5287,11 @@ snapshots: shebang-regex@3.0.0: {} - slash@3.0.0: {} + short-unique-id@5.2.0: {} + + sisteransi@1.0.5: {} + + slashes@3.0.12: {} snake-case@3.0.4: dependencies: @@ -4196,20 +5382,50 @@ snapshots: dependencies: svg.js: 2.7.1 + synckit@0.6.2: + dependencies: + tslib: 2.8.1 + + synckit@0.9.2: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.8.1 + + tapable@2.2.1: {} + + tinyexec@0.3.1: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 + toml-eslint-parser@0.10.0: + dependencies: + eslint-visitor-keys: 3.4.3 + ts-api-utils@1.4.0(typescript@5.6.3): dependencies: typescript: 5.6.3 + ts-declaration-location@1.0.4(typescript@5.6.3): + dependencies: + minimatch: 10.0.1 + typescript: 5.6.3 + + ts-pattern@5.5.0: {} + tslib@2.8.1: {} type-check@0.4.0: dependencies: prelude-ls: 1.2.1 + type-fest@0.20.2: {} + + type-fest@0.6.0: {} + + type-fest@0.8.1: {} + typescript-eslint@8.15.0(eslint@9.15.0)(typescript@5.6.3): dependencies: '@typescript-eslint/eslint-plugin': 8.15.0(@typescript-eslint/parser@8.15.0(eslint@9.15.0)(typescript@5.6.3))(eslint@9.15.0)(typescript@5.6.3) @@ -4256,6 +5472,13 @@ snapshots: dependencies: punycode: 2.3.1 + util-deprecate@1.0.2: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + vite-plugin-svgr@4.3.0(rollup@4.27.3)(typescript@5.6.3)(vite@5.4.11(@types/node@22.9.0)): dependencies: '@rollup/pluginutils': 5.1.3(rollup@4.27.3) @@ -4311,11 +5534,11 @@ snapshots: dependencies: eslint-visitor-keys: 3.4.3 lodash: 4.17.21 - yaml: 2.6.0 + yaml: 2.6.1 yaml@1.10.2: {} - yaml@2.6.0: {} + yaml@2.6.1: {} yargs-parser@21.1.1: {} diff --git a/vinvoor/src/settings/Settings.tsx b/vinvoor/src/settings/Settings.tsx index 730ed22..9497646 100644 --- a/vinvoor/src/settings/Settings.tsx +++ b/vinvoor/src/settings/Settings.tsx @@ -1,3 +1,6 @@ +import type { + SelectChangeEvent, +} from "@mui/material"; import { Box, Button,