This is an automated email from the ASF dual-hosted git repository.

jshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new 4eddf77bbc feat(tests): Add unit tests for web UI Oauth logic (#8232)
4eddf77bbc is described below

commit 4eddf77bbc8def174b48aaa991e37b05b4cee26f
Author: Bharath Krishna <[email protected]>
AuthorDate: Mon Aug 25 20:45:23 2025 -0700

    feat(tests): Add unit tests for web UI Oauth logic (#8232)
    
    ### What changes were proposed in this pull request?
    Add some vitest based tests for the OAuth login components for the react
    JS code
    
    ### Why are the changes needed?
    
    These changes were newly added so adding a few tests to make sure things
    work properly
    
    Fix: #(issue)
    
    ### Does this PR introduce _any_ user-facing change?
    No
    ### How was this patch tested?
    The tests are ran as Gitlab workflow. The `web-ui-tests` step is passing
    on the PR
---
 .github/workflows/web-ui-tests.yml             |   53 +
 web/web/LICENSE.bin                            |    8 +
 web/web/package.json                           |   10 +-
 web/web/pnpm-lock.yaml                         | 1304 +++++++++++++++++++++++-
 web/web/src/lib/auth/providers/factory.test.js |  205 ++++
 web/web/src/lib/auth/providers/oidc.test.js    |  312 ++++++
 web/web/src/test/setup.js                      |   30 +
 web/web/vitest.config.js                       |   51 +
 8 files changed, 1965 insertions(+), 8 deletions(-)

diff --git a/.github/workflows/web-ui-tests.yml 
b/.github/workflows/web-ui-tests.yml
new file mode 100644
index 0000000000..0df1a848ec
--- /dev/null
+++ b/.github/workflows/web-ui-tests.yml
@@ -0,0 +1,53 @@
+name: Web UI Tests
+
+on:
+  push:
+    branches: [ "main", "branch-*" ]
+    paths:
+      - 'web/web/**'
+      - '.github/workflows/web-ui-tests.yml'
+  pull_request:
+    branches: [ "main", "branch-*" ]
+    paths:
+      - 'web/web/**'
+      - '.github/workflows/web-ui-tests.yml'
+
+jobs:
+  test:
+    runs-on: ubuntu-latest
+    
+    steps:
+    - name: Checkout code
+      uses: actions/checkout@v4
+    
+    - name: Setup pnpm
+      uses: pnpm/action-setup@v4
+      with:
+        version: 9
+    
+    - name: Setup Node.js 20
+      uses: actions/setup-node@v4
+      with:
+        node-version: 20
+        cache: 'pnpm'
+        cache-dependency-path: 'web/web/pnpm-lock.yaml'
+    
+    - name: Install dependencies
+      working-directory: web/web
+      run: pnpm install --frozen-lockfile
+    
+    - name: Run linting
+      working-directory: web/web
+      run: pnpm lint
+    
+    - name: Run prettier check
+      working-directory: web/web
+      run: pnpm prettier:check
+    
+    - name: Run tests
+      working-directory: web/web
+      run: pnpm test:coverage
+
+    - name: Build application
+      working-directory: web/web
+      run: pnpm build
diff --git a/web/web/LICENSE.bin b/web/web/LICENSE.bin
index f815a48085..e058884fce 100644
--- a/web/web/LICENSE.bin
+++ b/web/web/LICENSE.bin
@@ -332,6 +332,12 @@
    @typescript-eslint/types
    @typescript-eslint/typescript-estree
    @typescript-eslint/visitor-keys
+   @vitest/coverage-v8
+   @vitest/expect
+   @vitest/runner
+   @vitest/snapshot
+   @vitest/spy
+   @vitest/utils
    @xobotyi/scrollbar-width
    acorn
    acorn-jsx
@@ -521,6 +527,7 @@
    js-cookie
    js-tokens
    js-yaml
+   jsdom
    json-buffer
    json-schema-traverse
    json-stable-stringify-without-jsonify
@@ -717,6 +724,7 @@
    update-browserslist-db
    use-sync-external-store
    util-deprecate
+   vitest
    webpack-bundle-analyzer
    which-boxed-primitive
    which-builtin-type
diff --git a/web/web/package.json b/web/web/package.json
index f3bfcfbae3..bd72adb86d 100644
--- a/web/web/package.json
+++ b/web/web/package.json
@@ -14,7 +14,10 @@
     "lint": "next lint",
     "format": "prettier --write .",
     "prettier:check": "prettier --check .",
-    "gen:icons": "tsx src/lib/icons/iconify-icons.js && prettier --write 
src/lib/icons/iconify-icons.css"
+    "gen:icons": "tsx src/lib/icons/iconify-icons.js && prettier --write 
src/lib/icons/iconify-icons.css",
+    "test": "vitest run",
+    "test:coverage": "vitest run --coverage",
+    "test:watch": "vitest --watch"
   },
   "dependencies": {
     "@emotion/cache": "^11.11.0",
@@ -53,15 +56,18 @@
     "@types/node": "^20.14.9",
     "@types/qs": "^6.9.18",
     "@types/react": "^18.3.3",
+    "@vitest/coverage-v8": "^1.6.0",
     "autoprefixer": "^10.4.21",
     "env-cmd": "^10.1.0",
     "eslint": "^8.57.0",
     "eslint-config-next": "14.0.3",
     "eslint-config-prettier": "^9.1.0",
+    "jsdom": "^24.1.0",
     "postcss": "^8.5.3",
     "prettier": "^3.3.2",
     "tailwindcss": "^3.4.4",
     "tsx": "^4.16.0",
-    "typescript": "^5.5.3"
+    "typescript": "^5.5.3",
+    "vitest": "^1.6.1"
   }
 }
diff --git a/web/web/pnpm-lock.yaml b/web/web/pnpm-lock.yaml
index 7914635e24..8bd7113869 100644
--- a/web/web/pnpm-lock.yaml
+++ b/web/web/pnpm-lock.yaml
@@ -34,7 +34,7 @@ importers:
         version: 
6.20.4(@mui/[email protected](@emotion/[email protected](@types/[email protected])([email protected]))(@emotion/[email protected](@emotion/[email protected](@types/[email protected])([email protected]))(@types/[email protected])([email protected]))(@types/[email protected])([email protected]([email protected]))([email protected]))(@mui/[email protected](@emotion/[email protected](@types/[email protected])([email protected]))(@emotion/[email protected](@emotion/[email protected](@types/[email protected])([email protected]))(@types/[email protected])([email protected]
 [...]
       '@reduxjs/toolkit':
         specifier: ^1.9.7
-        version: 
1.9.7([email protected](@types/[email protected])([email protected]([email protected]))([email protected])([email protected]))([email protected])
+        version: 
1.9.7([email protected](@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])([email protected]))([email protected])
       antd:
         specifier: ^5.24.5
         version: 5.26.4([email protected]([email protected]))([email protected])
@@ -79,7 +79,7 @@ importers:
         version: 2.5.2([email protected]([email protected]))([email protected])
       react-redux:
         specifier: ^8.1.3
-        version: 
8.1.3(@types/[email protected])([email protected]([email protected]))([email protected])([email protected])
+        version: 
8.1.3(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])([email protected])
       react-use:
         specifier: ^17.5.0
         version: 17.6.0([email protected]([email protected]))([email protected])
@@ -111,6 +111,9 @@ importers:
       '@types/react':
         specifier: ^18.3.3
         version: 18.3.23
+      '@vitest/coverage-v8':
+        specifier: ^1.6.0
+        version: 1.6.1([email protected])
       autoprefixer:
         specifier: ^10.4.21
         version: 10.4.21([email protected])
@@ -126,6 +129,9 @@ importers:
       eslint-config-prettier:
         specifier: ^9.1.0
         version: 9.1.0([email protected])
+      jsdom:
+        specifier: ^24.1.0
+        version: 24.1.3
       postcss:
         specifier: ^8.5.3
         version: 8.5.6
@@ -141,6 +147,9 @@ importers:
       typescript:
         specifier: ^5.5.3
         version: 5.8.3
+      vitest:
+        specifier: ^1.6.1
+        version: 1.6.1(@types/[email protected])(@vitest/[email protected])([email protected])
 
 packages:
 
@@ -148,6 +157,10 @@ packages:
     resolution: {integrity: 
sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
     engines: {node: '>=10'}
 
+  '@ampproject/[email protected]':
+    resolution: {integrity: 
sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
+    engines: {node: '>=6.0.0'}
+
   '@ant-design/[email protected]':
     resolution: {integrity: 
sha512-lCHDcEzieu4GA3n8ELeZ5VQ8pKQAWcGGLRTQ50aQM2iqPpq2evTxER84jfdPvsPAtEcZ7m44NI45edFMo8oOYQ==}
 
@@ -188,6 +201,9 @@ packages:
   '@antfu/[email protected]':
     resolution: {integrity: 
sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==}
 
+  '@asamuzakjp/[email protected]':
+    resolution: {integrity: 
sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==}
+
   '@babel/[email protected]':
     resolution: {integrity: 
sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
     engines: {node: '>=6.9.0'}
@@ -233,6 +249,37 @@ packages:
     resolution: {integrity: 
sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==}
     engines: {node: '>=6.9.0'}
 
+  '@bcoe/[email protected]':
+    resolution: {integrity: 
sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
+
+  '@csstools/[email protected]':
+    resolution: {integrity: 
sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==}
+    engines: {node: '>=18'}
+
+  '@csstools/[email protected]':
+    resolution: {integrity: 
sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==}
+    engines: {node: '>=18'}
+    peerDependencies:
+      '@csstools/css-parser-algorithms': ^3.0.5
+      '@csstools/css-tokenizer': ^3.0.4
+
+  '@csstools/[email protected]':
+    resolution: {integrity: 
sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==}
+    engines: {node: '>=18'}
+    peerDependencies:
+      '@csstools/css-parser-algorithms': ^3.0.5
+      '@csstools/css-tokenizer': ^3.0.4
+
+  '@csstools/[email protected]':
+    resolution: {integrity: 
sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==}
+    engines: {node: '>=18'}
+    peerDependencies:
+      '@csstools/css-tokenizer': ^3.0.4
+
+  '@csstools/[email protected]':
+    resolution: {integrity: 
sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==}
+    engines: {node: '>=18'}
+
   '@discoveryjs/[email protected]':
     resolution: {integrity: 
sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==}
     engines: {node: '>=10.0.0'}
@@ -306,102 +353,204 @@ packages:
   '@emotion/[email protected]':
     resolution: {integrity: 
sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==}
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+    engines: {node: '>=12'}
+    cpu: [ppc64]
+    os: [aix]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==}
     engines: {node: '>=18'}
     cpu: [ppc64]
     os: [aix]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [android]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [android]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [android]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==}
     engines: {node: '>=18'}
     cpu: [arm]
     os: [android]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [android]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [android]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [darwin]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [darwin]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [darwin]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [darwin]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [freebsd]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [freebsd]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [freebsd]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [freebsd]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [linux]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [linux]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [linux]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==}
     engines: {node: '>=18'}
     cpu: [arm]
     os: [linux]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [linux]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==}
     engines: {node: '>=18'}
     cpu: [ia32]
     os: [linux]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+    engines: {node: '>=12'}
+    cpu: [loong64]
+    os: [linux]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==}
     engines: {node: '>=18'}
     cpu: [loong64]
     os: [linux]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+    engines: {node: '>=12'}
+    cpu: [mips64el]
+    os: [linux]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==}
     engines: {node: '>=18'}
     cpu: [mips64el]
     os: [linux]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+    engines: {node: '>=12'}
+    cpu: [ppc64]
+    os: [linux]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==}
     engines: {node: '>=18'}
     cpu: [ppc64]
     os: [linux]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
+    engines: {node: '>=12'}
+    cpu: [riscv64]
+    os: [linux]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==}
     engines: {node: '>=18'}
     cpu: [riscv64]
     os: [linux]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
+    engines: {node: '>=12'}
+    cpu: [s390x]
+    os: [linux]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==}
     engines: {node: '>=18'}
     cpu: [s390x]
     os: [linux]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [linux]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==}
     engines: {node: '>=18'}
@@ -414,6 +563,12 @@ packages:
     cpu: [arm64]
     os: [netbsd]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [netbsd]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==}
     engines: {node: '>=18'}
@@ -426,6 +581,12 @@ packages:
     cpu: [arm64]
     os: [openbsd]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [openbsd]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==}
     engines: {node: '>=18'}
@@ -438,24 +599,48 @@ packages:
     cpu: [arm64]
     os: [openharmony]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [sunos]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [sunos]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [win32]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [win32]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [win32]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==}
     engines: {node: '>=18'}
     cpu: [ia32]
     os: [win32]
 
+  '@esbuild/[email protected]':
+    resolution: {integrity: 
sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [win32]
+
   '@esbuild/[email protected]':
     resolution: {integrity: 
sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==}
     engines: {node: '>=18'}
@@ -531,6 +716,14 @@ packages:
     resolution: {integrity: 
sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
     engines: {node: '>=12'}
 
+  '@istanbuljs/[email protected]':
+    resolution: {integrity: 
sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
+    engines: {node: '>=8'}
+
+  '@jest/[email protected]':
+    resolution: {integrity: 
sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
+    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
   '@jridgewell/[email protected]':
     resolution: {integrity: 
sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==}
 
@@ -829,12 +1022,115 @@ packages:
       react-redux:
         optional: true
 
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==}
+    cpu: [arm]
+    os: [android]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==}
+    cpu: [arm64]
+    os: [android]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==}
+    cpu: [arm64]
+    os: [darwin]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==}
+    cpu: [x64]
+    os: [darwin]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==}
+    cpu: [arm64]
+    os: [freebsd]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==}
+    cpu: [x64]
+    os: [freebsd]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==}
+    cpu: [arm]
+    os: [linux]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==}
+    cpu: [arm]
+    os: [linux]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==}
+    cpu: [arm64]
+    os: [linux]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==}
+    cpu: [arm64]
+    os: [linux]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==}
+    cpu: [loong64]
+    os: [linux]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==}
+    cpu: [ppc64]
+    os: [linux]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==}
+    cpu: [riscv64]
+    os: [linux]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==}
+    cpu: [riscv64]
+    os: [linux]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==}
+    cpu: [s390x]
+    os: [linux]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==}
+    cpu: [x64]
+    os: [linux]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==}
+    cpu: [x64]
+    os: [linux]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==}
+    cpu: [arm64]
+    os: [win32]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==}
+    cpu: [ia32]
+    os: [win32]
+
+  '@rollup/[email protected]':
+    resolution: {integrity: 
sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==}
+    cpu: [x64]
+    os: [win32]
+
   '@rtsao/[email protected]':
     resolution: {integrity: 
sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
 
   '@rushstack/[email protected]':
     resolution: {integrity: 
sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==}
 
+  '@sinclair/[email protected]':
+    resolution: {integrity: 
sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
+
   '@swc/[email protected]':
     resolution: {integrity: 
sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
 
@@ -848,6 +1144,9 @@ packages:
   '@tybys/[email protected]':
     resolution: {integrity: 
sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==}
 
+  '@types/[email protected]':
+    resolution: {integrity: 
sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+
   '@types/[email protected]':
     resolution: {integrity: 
sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==}
 
@@ -875,6 +1174,11 @@ packages:
   '@types/[email protected]':
     resolution: {integrity: 
sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==}
 
+  '@types/[email protected]':
+    resolution: {integrity: 
sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==}
+    peerDependencies:
+      '@types/react': ^18.0.0
+
   '@types/[email protected]':
     resolution: {integrity: 
sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==}
     peerDependencies:
@@ -1021,6 +1325,31 @@ packages:
     cpu: [x64]
     os: [win32]
 
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-6YeRZwuO4oTGKxD3bijok756oktHSIm3eczVVzNe3scqzuhLwltIF3S9ZL/vwOVIpURmU6SnZhziXXAfw8/Qlw==}
+    peerDependencies:
+      vitest: 1.6.1
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==}
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==}
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==}
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==}
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-xa57bCPGuzEFqGjPs3vVLyqareG8DX0uMkr5U/v5vLv5/ZUrBrPL7gzxzTJedEyZxFMfsozwTIbbYfEQVo3kgg==}
+    peerDependencies:
+      vitest: 1.6.1
+
+  '@vitest/[email protected]':
+    resolution: {integrity: 
sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==}
+
   '@xobotyi/[email protected]':
     resolution: {integrity: 
sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==}
 
@@ -1038,6 +1367,10 @@ packages:
     engines: {node: '>=0.4.0'}
     hasBin: true
 
+  [email protected]:
+    resolution: {integrity: 
sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
+    engines: {node: '>= 14'}
+
   [email protected]:
     resolution: {integrity: 
sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
 
@@ -1053,6 +1386,10 @@ packages:
     resolution: {integrity: 
sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
     engines: {node: '>=8'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
+    engines: {node: '>=10'}
+
   [email protected]:
     resolution: {integrity: 
sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
     engines: {node: '>=12'}
@@ -1116,6 +1453,9 @@ packages:
     resolution: {integrity: 
sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
     engines: {node: '>= 0.4'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
+
   [email protected]:
     resolution: {integrity: 
sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==}
 
@@ -1184,6 +1524,10 @@ packages:
     resolution: {integrity: 
sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
     engines: {node: '>=10.16.0'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
+    engines: {node: '>=8'}
+
   [email protected]:
     resolution: {integrity: 
sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
     engines: {node: '>= 0.4'}
@@ -1207,10 +1551,17 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==}
+    engines: {node: '>=4'}
+
   [email protected]:
     resolution: {integrity: 
sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
     engines: {node: '>=10'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==}
+
   [email protected]:
     resolution: {integrity: 
sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
 
@@ -1315,12 +1666,20 @@ packages:
     resolution: {integrity: 
sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
     engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==}
+    engines: {node: '>=18'}
+
   [email protected]:
     resolution: {integrity: 
sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
 
   [email protected]:
     resolution: {integrity: 
sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==}
+    engines: {node: '>=18'}
+
   [email protected]:
     resolution: {integrity: 
sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
     engines: {node: '>= 0.4'}
@@ -1356,6 +1715,13 @@ packages:
       supports-color:
         optional: true
 
+  [email protected]:
+    resolution: {integrity: 
sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==}
+    engines: {node: '>=6'}
+
   [email protected]:
     resolution: {integrity: 
sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
 
@@ -1374,6 +1740,10 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
+    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
   [email protected]:
     resolution: {integrity: 
sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
     engines: {node: '>=8'}
@@ -1481,6 +1851,11 @@ packages:
     resolution: {integrity: 
sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
     engines: {node: '>= 0.4'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+    engines: {node: '>=12'}
+    hasBin: true
+
   [email protected]:
     resolution: {integrity: 
sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==}
     engines: {node: '>=18'}
@@ -1604,10 +1979,17 @@ packages:
     resolution: {integrity: 
sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
     engines: {node: '>=4.0'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
   [email protected]:
     resolution: {integrity: 
sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
     engines: {node: '>=0.10.0'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
+    engines: {node: '>=16.17'}
+
   [email protected]:
     resolution: {integrity: 
sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==}
 
@@ -1649,6 +2031,9 @@ packages:
       picomatch:
         optional: true
 
+  [email protected]:
+    resolution: {integrity: 
sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
+
   [email protected]:
     resolution: {integrity: 
sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
     engines: {node: ^10.12.0 || >=12.0.0}
@@ -1717,6 +2102,9 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
+
   [email protected]:
     resolution: {integrity: 
sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
     engines: {node: '>= 0.4'}
@@ -1729,6 +2117,10 @@ packages:
     resolution: {integrity: 
sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
     engines: {node: '>=8'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
+    engines: {node: '>=16'}
+
   [email protected]:
     resolution: {integrity: 
sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
     engines: {node: '>= 0.4'}
@@ -1821,12 +2213,28 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
+    engines: {node: '>=18'}
+
   [email protected]:
     resolution: {integrity: 
sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
 
   [email protected]:
     resolution: {integrity: 
sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
+    engines: {node: '>= 14'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
+    engines: {node: '>= 14'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
+    engines: {node: '>=16.17.0'}
+
   [email protected]:
     resolution: {integrity: 
sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==}
 
@@ -1949,6 +2357,9 @@ packages:
     resolution: {integrity: 
sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
     engines: {node: '>=0.10.0'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
+
   [email protected]:
     resolution: {integrity: 
sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
     engines: {node: '>= 0.4'}
@@ -1961,6 +2372,10 @@ packages:
     resolution: {integrity: 
sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
     engines: {node: '>= 0.4'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
+    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
   [email protected]:
     resolution: {integrity: 
sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
     engines: {node: '>= 0.4'}
@@ -1991,6 +2406,22 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
+    engines: {node: '>=8'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
+    engines: {node: '>=10'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==}
+    engines: {node: '>=10'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==}
+    engines: {node: '>=8'}
+
   [email protected]:
     resolution: {integrity: 
sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
     engines: {node: '>= 0.4'}
@@ -2008,10 +2439,22 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
+
   [email protected]:
     resolution: {integrity: 
sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
     hasBin: true
 
+  [email protected]:
+    resolution: {integrity: 
sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==}
+    engines: {node: '>=18'}
+    peerDependencies:
+      canvas: ^2.11.2
+    peerDependenciesMeta:
+      canvas:
+        optional: true
+
   [email protected]:
     resolution: {integrity: 
sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
     engines: {node: '>=6'}
@@ -2090,9 +2533,22 @@ packages:
     resolution: {integrity: 
sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
     hasBin: true
 
+  [email protected]:
+    resolution: {integrity: 
sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==}
+
   [email protected]:
     resolution: {integrity: 
sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
+    engines: {node: '>=10'}
+
   [email protected]:
     resolution: {integrity: 
sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
     engines: {node: '>= 0.4'}
@@ -2106,6 +2562,9 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+
   [email protected]:
     resolution: {integrity: 
sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
     engines: {node: '>= 8'}
@@ -2122,6 +2581,10 @@ packages:
     resolution: {integrity: 
sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
     engines: {node: '>= 0.6'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
+    engines: {node: '>=12'}
+
   [email protected]:
     resolution: {integrity: 
sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
 
@@ -2222,12 +2685,19 @@ packages:
     resolution: {integrity: 
sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
     engines: {node: '>=0.10.0'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
+    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
   [email protected]:
     resolution: {integrity: 
sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==}
 
   [email protected]:
     resolution: {integrity: 
sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==}
+
   [email protected]:
     resolution: {integrity: 
sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
     engines: {node: '>=0.10.0'}
@@ -2271,6 +2741,10 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
+    engines: {node: '>=12'}
+
   [email protected]:
     resolution: {integrity: 
sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==}
     hasBin: true
@@ -2287,6 +2761,10 @@ packages:
     resolution: {integrity: 
sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
     engines: {node: '>=10'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==}
+    engines: {node: '>=18'}
+
   [email protected]:
     resolution: {integrity: 
sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
     engines: {node: '>=10'}
@@ -2326,6 +2804,10 @@ packages:
     resolution: {integrity: 
sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
     engines: {node: '>=8'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
+    engines: {node: '>=12'}
+
   [email protected]:
     resolution: {integrity: 
sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
 
@@ -2343,6 +2825,9 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
+
   [email protected]:
     resolution: {integrity: 
sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
 
@@ -2429,6 +2914,10 @@ packages:
     engines: {node: '>=14'}
     hasBin: true
 
+  [email protected]:
+    resolution: {integrity: 
sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
+    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
   [email protected]:
     resolution: {integrity: 
sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
 
@@ -2438,6 +2927,9 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
+
   [email protected]:
     resolution: {integrity: 
sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==}
 
@@ -2452,6 +2944,9 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
+
   [email protected]:
     resolution: {integrity: 
sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
 
@@ -2776,6 +3271,9 @@ packages:
     resolution: {integrity: 
sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
     engines: {node: '>= 0.4'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
+
   [email protected]:
     resolution: {integrity: 
sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==}
 
@@ -2807,6 +3305,17 @@ packages:
     deprecated: Rimraf versions prior to v4 are no longer supported
     hasBin: true
 
+  [email protected]:
+    resolution: {integrity: 
sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==}
+    engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==}
+
   [email protected]:
     resolution: {integrity: 
sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==}
 
@@ -2828,6 +3337,10 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
+    engines: {node: '>=v12.22.7'}
+
   [email protected]:
     resolution: {integrity: 
sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
 
@@ -2887,6 +3400,9 @@ packages:
     resolution: {integrity: 
sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
     engines: {node: '>= 0.4'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
   [email protected]:
     resolution: {integrity: 
sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
     engines: {node: '>=14'}
@@ -2921,6 +3437,9 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
   [email protected]:
     resolution: {integrity: 
sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==}
 
@@ -2930,6 +3449,9 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==}
+
   [email protected]:
     resolution: {integrity: 
sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
     engines: {node: '>= 0.4'}
@@ -2984,10 +3506,17 @@ packages:
     resolution: {integrity: 
sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
     engines: {node: '>=4'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
+    engines: {node: '>=12'}
+
   [email protected]:
     resolution: {integrity: 
sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
     engines: {node: '>=8'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==}
+
   [email protected]:
     resolution: {integrity: 
sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==}
     engines: {node: '>= 12.0.0'}
@@ -3025,6 +3554,9 @@ packages:
     engines: {node: '>=14.0.0'}
     hasBin: true
 
+  [email protected]:
+    resolution: {integrity: 
sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
+
   [email protected]:
     resolution: {integrity: 
sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==}
     engines: {node: '>=14.0.0'}
@@ -3034,6 +3566,10 @@ packages:
     resolution: {integrity: 
sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
     engines: {node: '>=10'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
+    engines: {node: '>=8'}
+
   [email protected]:
     resolution: {integrity: 
sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
 
@@ -3055,6 +3591,9 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
   [email protected]:
     resolution: {integrity: 
sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==}
 
@@ -3062,6 +3601,14 @@ packages:
     resolution: {integrity: 
sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
     engines: {node: '>=12.0.0'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==}
+    engines: {node: '>=14.0.0'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==}
+    engines: {node: '>=14.0.0'}
+
   [email protected]:
     resolution: {integrity: 
sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
     engines: {node: '>=8.0'}
@@ -3076,6 +3623,14 @@ packages:
     resolution: {integrity: 
sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
     engines: {node: '>=6'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==}
+    engines: {node: '>=6'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==}
+    engines: {node: '>=18'}
+
   [email protected]:
     resolution: {integrity: 
sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==}
     engines: {node: '>=16'}
@@ -3103,6 +3658,10 @@ packages:
     resolution: {integrity: 
sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
     engines: {node: '>= 0.8.0'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==}
+    engines: {node: '>=4'}
+
   [email protected]:
     resolution: {integrity: 
sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
     engines: {node: '>=10'}
@@ -3146,6 +3705,10 @@ packages:
     resolution: {integrity: 
sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==}
     engines: {node: '>=18.17'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
+    engines: {node: '>= 4.0.0'}
+
   [email protected]:
     resolution: {integrity: 
sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==}
 
@@ -3158,6 +3721,9 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
+
   [email protected]:
     resolution: {integrity: 
sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==}
     peerDependencies:
@@ -3166,6 +3732,75 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==}
+    engines: {node: ^18.0.0 || >=20.0.0}
+    hasBin: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==}
+    engines: {node: ^18.0.0 || >=20.0.0}
+    hasBin: true
+    peerDependencies:
+      '@types/node': ^18.0.0 || >=20.0.0
+      less: '*'
+      lightningcss: ^1.21.0
+      sass: '*'
+      sass-embedded: '*'
+      stylus: '*'
+      sugarss: '*'
+      terser: ^5.4.0
+    peerDependenciesMeta:
+      '@types/node':
+        optional: true
+      less:
+        optional: true
+      lightningcss:
+        optional: true
+      sass:
+        optional: true
+      sass-embedded:
+        optional: true
+      stylus:
+        optional: true
+      sugarss:
+        optional: true
+      terser:
+        optional: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==}
+    engines: {node: ^18.0.0 || >=20.0.0}
+    hasBin: true
+    peerDependencies:
+      '@edge-runtime/vm': '*'
+      '@types/node': ^18.0.0 || >=20.0.0
+      '@vitest/browser': 1.6.1
+      '@vitest/ui': 1.6.1
+      happy-dom: '*'
+      jsdom: '*'
+    peerDependenciesMeta:
+      '@edge-runtime/vm':
+        optional: true
+      '@types/node':
+        optional: true
+      '@vitest/browser':
+        optional: true
+      '@vitest/ui':
+        optional: true
+      happy-dom:
+        optional: true
+      jsdom:
+        optional: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
+    engines: {node: '>=18'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
+    engines: {node: '>=12'}
+
   [email protected]:
     resolution: {integrity: 
sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==}
     engines: {node: '>= 10.13.0'}
@@ -3179,6 +3814,10 @@ packages:
     resolution: {integrity: 
sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
     engines: {node: '>=18'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==}
+    engines: {node: '>=18'}
+
   [email protected]:
     resolution: {integrity: 
sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
     engines: {node: '>= 0.4'}
@@ -3200,6 +3839,11 @@ packages:
     engines: {node: '>= 8'}
     hasBin: true
 
+  [email protected]:
+    resolution: {integrity: 
sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+    engines: {node: '>=8'}
+    hasBin: true
+
   [email protected]:
     resolution: {integrity: 
sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
     engines: {node: '>=0.10.0'}
@@ -3227,6 +3871,25 @@ packages:
       utf-8-validate:
         optional: true
 
+  [email protected]:
+    resolution: {integrity: 
sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
+    engines: {node: '>=10.0.0'}
+    peerDependencies:
+      bufferutil: ^4.0.1
+      utf-8-validate: '>=5.0.2'
+    peerDependenciesMeta:
+      bufferutil:
+        optional: true
+      utf-8-validate:
+        optional: true
+
+  [email protected]:
+    resolution: {integrity: 
sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
+    engines: {node: '>=18'}
+
+  [email protected]:
+    resolution: {integrity: 
sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
+
   [email protected]:
     resolution: {integrity: 
sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
 
@@ -3246,6 +3909,10 @@ packages:
     resolution: {integrity: 
sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
     engines: {node: '>=10'}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==}
+    engines: {node: '>=12.20'}
+
   [email protected]:
     resolution: {integrity: 
sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==}
 
@@ -3253,6 +3920,11 @@ snapshots:
 
   '@alloc/[email protected]': {}
 
+  '@ampproject/[email protected]':
+    dependencies:
+      '@jridgewell/gen-mapping': 0.3.12
+      '@jridgewell/trace-mapping': 0.3.29
+
   '@ant-design/[email protected]':
     dependencies:
       '@ant-design/fast-color': 2.0.6
@@ -3309,6 +3981,14 @@ snapshots:
 
   '@antfu/[email protected]': {}
 
+  '@asamuzakjp/[email protected]':
+    dependencies:
+      '@csstools/css-calc': 
2.1.4(@csstools/[email protected](@csstools/[email protected]))(@csstools/[email protected])
+      '@csstools/css-color-parser': 
3.0.10(@csstools/[email protected](@csstools/[email protected]))(@csstools/[email protected])
+      '@csstools/css-parser-algorithms': 3.0.5(@csstools/[email protected])
+      '@csstools/css-tokenizer': 3.0.4
+      lru-cache: 10.4.3
+
   '@babel/[email protected]':
     dependencies:
       '@babel/helper-validator-identifier': 7.27.1
@@ -3365,6 +4045,28 @@ snapshots:
       '@babel/helper-string-parser': 7.27.1
       '@babel/helper-validator-identifier': 7.27.1
 
+  '@bcoe/[email protected]': {}
+
+  '@csstools/[email protected]': {}
+
+  
'@csstools/[email protected](@csstools/[email protected](@csstools/[email protected]))(@csstools/[email protected])':
+    dependencies:
+      '@csstools/css-parser-algorithms': 3.0.5(@csstools/[email protected])
+      '@csstools/css-tokenizer': 3.0.4
+
+  
'@csstools/[email protected](@csstools/[email protected](@csstools/[email protected]))(@csstools/[email protected])':
+    dependencies:
+      '@csstools/color-helpers': 5.0.2
+      '@csstools/css-calc': 
2.1.4(@csstools/[email protected](@csstools/[email protected]))(@csstools/[email protected])
+      '@csstools/css-parser-algorithms': 3.0.5(@csstools/[email protected])
+      '@csstools/css-tokenizer': 3.0.4
+
+  '@csstools/[email protected](@csstools/[email protected])':
+    dependencies:
+      '@csstools/css-tokenizer': 3.0.4
+
+  '@csstools/[email protected]': {}
+
   '@discoveryjs/[email protected]': {}
 
   '@emnapi/[email protected]':
@@ -3470,52 +4172,103 @@ snapshots:
 
   '@emotion/[email protected]': {}
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
-  '@esbuild/[email protected]':
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
+    optional: true
+
+  '@esbuild/[email protected]':
     optional: true
 
   '@esbuild/[email protected]':
@@ -3524,27 +4277,45 @@ snapshots:
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
+  '@esbuild/[email protected]':
+    optional: true
+
   '@esbuild/[email protected]':
     optional: true
 
@@ -3650,6 +4421,12 @@ snapshots:
       wrap-ansi: 8.1.0
       wrap-ansi-cjs: [email protected]
 
+  '@istanbuljs/[email protected]': {}
+
+  '@jest/[email protected]':
+    dependencies:
+      '@sinclair/typebox': 0.27.8
+
   '@jridgewell/[email protected]':
     dependencies:
       '@jridgewell/sourcemap-codec': 1.5.4
@@ -3930,7 +4707,7 @@ snapshots:
       react: 18.3.1
       react-dom: 18.3.1([email protected])
 
-  
'@reduxjs/[email protected]([email protected](@types/[email protected])([email protected]([email protected]))([email protected])([email protected]))([email protected])':
+  
'@reduxjs/[email protected]([email protected](@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])([email protected]))([email protected])':
     dependencies:
       immer: 9.0.21
       redux: 4.2.1
@@ -3938,12 +4715,74 @@ snapshots:
       reselect: 4.1.8
     optionalDependencies:
       react: 18.3.1
-      react-redux: 
8.1.3(@types/[email protected])([email protected]([email protected]))([email protected])([email protected])
+      react-redux: 
8.1.3(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])([email protected])
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
+
+  '@rollup/[email protected]':
+    optional: true
 
   '@rtsao/[email protected]': {}
 
   '@rushstack/[email protected]': {}
 
+  '@sinclair/[email protected]': {}
+
   '@swc/[email protected]': {}
 
   '@swc/[email protected]':
@@ -3958,6 +4797,8 @@ snapshots:
       tslib: 2.8.1
     optional: true
 
+  '@types/[email protected]': {}
+
   '@types/[email protected]':
     dependencies:
       '@types/react': 18.3.23
@@ -3983,6 +4824,11 @@ snapshots:
 
   '@types/[email protected]': {}
 
+  '@types/[email protected](@types/[email protected])':
+    dependencies:
+      '@types/react': 18.3.23
+    optional: true
+
   '@types/[email protected](@types/[email protected])':
     dependencies:
       '@types/react': 18.3.23
@@ -4105,6 +4951,66 @@ snapshots:
   '@unrs/[email protected]':
     optional: true
 
+  '@vitest/[email protected]([email protected])':
+    dependencies:
+      '@ampproject/remapping': 2.3.0
+      '@bcoe/v8-coverage': 0.2.3
+      debug: 4.4.1
+      istanbul-lib-coverage: 3.2.2
+      istanbul-lib-report: 3.0.1
+      istanbul-lib-source-maps: 5.0.6
+      istanbul-reports: 3.1.7
+      magic-string: 0.30.17
+      magicast: 0.3.5
+      picocolors: 1.1.1
+      std-env: 3.9.0
+      strip-literal: 2.1.1
+      test-exclude: 6.0.0
+      vitest: 1.6.1(@types/[email protected])(@vitest/[email protected])([email protected])
+    transitivePeerDependencies:
+      - supports-color
+
+  '@vitest/[email protected]':
+    dependencies:
+      '@vitest/spy': 1.6.1
+      '@vitest/utils': 1.6.1
+      chai: 4.5.0
+
+  '@vitest/[email protected]':
+    dependencies:
+      '@vitest/utils': 1.6.1
+      p-limit: 5.0.0
+      pathe: 1.1.2
+
+  '@vitest/[email protected]':
+    dependencies:
+      magic-string: 0.30.17
+      pathe: 1.1.2
+      pretty-format: 29.7.0
+
+  '@vitest/[email protected]':
+    dependencies:
+      tinyspy: 2.2.1
+
+  '@vitest/[email protected]([email protected])':
+    dependencies:
+      '@vitest/utils': 1.6.1
+      fast-glob: 3.3.3
+      fflate: 0.8.2
+      flatted: 3.3.3
+      pathe: 1.1.2
+      picocolors: 1.1.1
+      sirv: 2.0.4
+      vitest: 1.6.1(@types/[email protected])(@vitest/[email protected])([email protected])
+    optional: true
+
+  '@vitest/[email protected]':
+    dependencies:
+      diff-sequences: 29.6.3
+      estree-walker: 3.0.3
+      loupe: 2.3.7
+      pretty-format: 29.7.0
+
   '@xobotyi/[email protected]': {}
 
   [email protected]([email protected]):
@@ -4117,6 +5023,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       fast-deep-equal: 3.1.3
@@ -4132,6 +5040,8 @@ snapshots:
     dependencies:
       color-convert: 2.0.1
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]([email protected]([email protected]))([email protected]):
@@ -4274,6 +5184,8 @@ snapshots:
       get-intrinsic: 1.3.0
       is-array-buffer: 3.0.5
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]: {}
@@ -4344,6 +5256,8 @@ snapshots:
     dependencies:
       streamsearch: 1.1.0
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       es-errors: 1.3.0
@@ -4367,11 +5281,25 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      assertion-error: 1.1.0
+      check-error: 1.0.3
+      deep-eql: 4.1.4
+      get-func-name: 2.0.2
+      loupe: 2.3.7
+      pathval: 1.1.1
+      type-detect: 4.1.0
+
   [email protected]:
     dependencies:
       ansi-styles: 4.3.0
       supports-color: 7.2.0
 
+  [email protected]:
+    dependencies:
+      get-func-name: 2.0.2
+
   [email protected]:
     dependencies:
       boolbase: 1.0.0
@@ -4494,10 +5422,20 @@ snapshots:
     dependencies:
       css-tree: 2.2.1
 
+  [email protected]:
+    dependencies:
+      '@asamuzakjp/css-color': 3.2.0
+      rrweb-cssom: 0.8.0
+
   [email protected]: {}
 
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      whatwg-mimetype: 4.0.0
+      whatwg-url: 14.2.0
+
   [email protected]:
     dependencies:
       call-bound: 1.0.4
@@ -4528,6 +5466,12 @@ snapshots:
     dependencies:
       ms: 2.1.3
 
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      type-detect: 4.1.0
+
   [email protected]: {}
 
   [email protected]:
@@ -4546,6 +5490,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       path-type: 4.0.0
@@ -4726,6 +5672,32 @@ snapshots:
       is-date-object: 1.1.0
       is-symbol: 1.1.1
 
+  [email protected]:
+    optionalDependencies:
+      '@esbuild/aix-ppc64': 0.21.5
+      '@esbuild/android-arm': 0.21.5
+      '@esbuild/android-arm64': 0.21.5
+      '@esbuild/android-x64': 0.21.5
+      '@esbuild/darwin-arm64': 0.21.5
+      '@esbuild/darwin-x64': 0.21.5
+      '@esbuild/freebsd-arm64': 0.21.5
+      '@esbuild/freebsd-x64': 0.21.5
+      '@esbuild/linux-arm': 0.21.5
+      '@esbuild/linux-arm64': 0.21.5
+      '@esbuild/linux-ia32': 0.21.5
+      '@esbuild/linux-loong64': 0.21.5
+      '@esbuild/linux-mips64el': 0.21.5
+      '@esbuild/linux-ppc64': 0.21.5
+      '@esbuild/linux-riscv64': 0.21.5
+      '@esbuild/linux-s390x': 0.21.5
+      '@esbuild/linux-x64': 0.21.5
+      '@esbuild/netbsd-x64': 0.21.5
+      '@esbuild/openbsd-x64': 0.21.5
+      '@esbuild/sunos-x64': 0.21.5
+      '@esbuild/win32-arm64': 0.21.5
+      '@esbuild/win32-ia32': 0.21.5
+      '@esbuild/win32-x64': 0.21.5
+
   [email protected]:
     optionalDependencies:
       '@esbuild/aix-ppc64': 0.25.6
@@ -4956,8 +5928,24 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      '@types/estree': 1.0.8
+
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      cross-spawn: 7.0.6
+      get-stream: 8.0.1
+      human-signals: 5.0.0
+      is-stream: 3.0.0
+      merge-stream: 2.0.0
+      npm-run-path: 5.3.0
+      onetime: 6.0.0
+      signal-exit: 4.1.0
+      strip-final-newline: 3.0.0
+
   [email protected]: {}
 
   [email protected]:
@@ -5000,6 +5988,9 @@ snapshots:
     optionalDependencies:
       picomatch: 4.0.2
 
+  [email protected]:
+    optional: true
+
   [email protected]:
     dependencies:
       flat-cache: 3.2.0
@@ -5066,6 +6057,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       call-bind-apply-helpers: 1.0.2
@@ -5088,6 +6081,8 @@ snapshots:
     dependencies:
       pump: 3.0.3
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       call-bound: 1.0.4
@@ -5193,6 +6188,10 @@ snapshots:
     dependencies:
       react-is: 16.13.1
 
+  [email protected]:
+    dependencies:
+      whatwg-encoding: 3.1.1
+
   [email protected]: {}
 
   [email protected]:
@@ -5202,6 +6201,22 @@ snapshots:
       domutils: 3.2.2
       entities: 4.5.0
 
+  [email protected]:
+    dependencies:
+      agent-base: 7.1.4
+      debug: 4.4.1
+    transitivePeerDependencies:
+      - supports-color
+
+  [email protected]:
+    dependencies:
+      agent-base: 7.1.4
+      debug: 4.4.1
+    transitivePeerDependencies:
+      - supports-color
+
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]:
@@ -5320,6 +6335,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       call-bound: 1.0.4
@@ -5333,6 +6350,8 @@ snapshots:
     dependencies:
       call-bound: 1.0.4
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       call-bound: 1.0.4
@@ -5363,6 +6382,27 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
+  [email protected]:
+    dependencies:
+      istanbul-lib-coverage: 3.2.2
+      make-dir: 4.0.0
+      supports-color: 7.2.0
+
+  [email protected]:
+    dependencies:
+      '@jridgewell/trace-mapping': 0.3.29
+      debug: 4.4.1
+      istanbul-lib-coverage: 3.2.2
+    transitivePeerDependencies:
+      - supports-color
+
+  [email protected]:
+    dependencies:
+      html-escaper: 2.0.2
+      istanbul-lib-report: 3.0.1
+
   [email protected]:
     dependencies:
       define-data-property: 1.1.4
@@ -5384,10 +6424,40 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       argparse: 2.0.1
 
+  [email protected]:
+    dependencies:
+      cssstyle: 4.6.0
+      data-urls: 5.0.0
+      decimal.js: 10.6.0
+      form-data: 4.0.3
+      html-encoding-sniffer: 4.0.0
+      http-proxy-agent: 7.0.2
+      https-proxy-agent: 7.0.6
+      is-potential-custom-element-name: 1.0.1
+      nwsapi: 2.2.21
+      parse5: 7.3.0
+      rrweb-cssom: 0.7.1
+      saxes: 6.0.0
+      symbol-tree: 3.2.4
+      tough-cookie: 4.1.4
+      w3c-xmlserializer: 5.0.0
+      webidl-conversions: 7.0.0
+      whatwg-encoding: 3.1.1
+      whatwg-mimetype: 4.0.0
+      whatwg-url: 14.2.0
+      ws: 8.18.3
+      xml-name-validator: 5.0.0
+    transitivePeerDependencies:
+      - bufferutil
+      - supports-color
+      - utf-8-validate
+
   [email protected]: {}
 
   [email protected]: {}
@@ -5459,8 +6529,26 @@ snapshots:
     dependencies:
       js-tokens: 4.0.0
 
+  [email protected]:
+    dependencies:
+      get-func-name: 2.0.2
+
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      '@jridgewell/sourcemap-codec': 1.5.4
+
+  [email protected]:
+    dependencies:
+      '@babel/parser': 7.28.0
+      '@babel/types': 7.28.0
+      source-map-js: 1.2.1
+
+  [email protected]:
+    dependencies:
+      semver: 7.7.2
+
   [email protected]: {}
 
   [email protected]: {}
@@ -5469,6 +6557,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]:
@@ -5482,6 +6572,8 @@ snapshots:
     dependencies:
       mime-db: 1.52.0
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       brace-expansion: 1.1.12
@@ -5580,12 +6672,18 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      path-key: 4.0.0
+
   [email protected]: {}
 
   [email protected]:
     dependencies:
       boolbase: 1.0.0
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]: {}
@@ -5638,6 +6736,10 @@ snapshots:
     dependencies:
       wrappy: 1.0.2
 
+  [email protected]:
+    dependencies:
+      mimic-fn: 4.0.0
+
   [email protected]: {}
 
   [email protected]:
@@ -5659,6 +6761,10 @@ snapshots:
     dependencies:
       yocto-queue: 0.1.0
 
+  [email protected]:
+    dependencies:
+      yocto-queue: 1.2.1
+
   [email protected]:
     dependencies:
       p-limit: 3.1.0
@@ -5697,6 +6803,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]:
@@ -5710,6 +6818,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]: {}
@@ -5783,6 +6893,12 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      '@jest/schemas': 29.6.3
+      ansi-styles: 5.2.0
+      react-is: 18.3.1
+
   [email protected]:
     dependencies:
       loose-envify: 1.4.0
@@ -5793,6 +6909,10 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      punycode: 2.3.1
+
   [email protected]:
     dependencies:
       end-of-stream: 1.4.5
@@ -5806,6 +6926,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]([email protected]([email protected]))([email protected]):
@@ -6150,7 +7272,7 @@ snapshots:
 
   [email protected]: {}
 
-  
[email protected](@types/[email protected])([email protected]([email protected]))([email protected])([email protected]):
+  
[email protected](@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected]([email protected]))([email protected])([email protected]):
     dependencies:
       '@babel/runtime': 7.27.6
       '@types/hoist-non-react-statics': 3.3.6
@@ -6161,6 +7283,7 @@ snapshots:
       use-sync-external-store: 1.5.0([email protected])
     optionalDependencies:
       '@types/react': 18.3.23
+      '@types/react-dom': 18.3.7(@types/[email protected])
       react-dom: 18.3.1([email protected])
       redux: 4.2.1
 
@@ -6237,6 +7360,8 @@ snapshots:
       gopd: 1.2.0
       set-function-name: 2.0.2
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]: {}
@@ -6263,6 +7388,36 @@ snapshots:
     dependencies:
       glob: 7.2.3
 
+  [email protected]:
+    dependencies:
+      '@types/estree': 1.0.8
+    optionalDependencies:
+      '@rollup/rollup-android-arm-eabi': 4.46.2
+      '@rollup/rollup-android-arm64': 4.46.2
+      '@rollup/rollup-darwin-arm64': 4.46.2
+      '@rollup/rollup-darwin-x64': 4.46.2
+      '@rollup/rollup-freebsd-arm64': 4.46.2
+      '@rollup/rollup-freebsd-x64': 4.46.2
+      '@rollup/rollup-linux-arm-gnueabihf': 4.46.2
+      '@rollup/rollup-linux-arm-musleabihf': 4.46.2
+      '@rollup/rollup-linux-arm64-gnu': 4.46.2
+      '@rollup/rollup-linux-arm64-musl': 4.46.2
+      '@rollup/rollup-linux-loongarch64-gnu': 4.46.2
+      '@rollup/rollup-linux-ppc64-gnu': 4.46.2
+      '@rollup/rollup-linux-riscv64-gnu': 4.46.2
+      '@rollup/rollup-linux-riscv64-musl': 4.46.2
+      '@rollup/rollup-linux-s390x-gnu': 4.46.2
+      '@rollup/rollup-linux-x64-gnu': 4.46.2
+      '@rollup/rollup-linux-x64-musl': 4.46.2
+      '@rollup/rollup-win32-arm64-msvc': 4.46.2
+      '@rollup/rollup-win32-ia32-msvc': 4.46.2
+      '@rollup/rollup-win32-x64-msvc': 4.46.2
+      fsevents: 2.3.3
+
+  [email protected]: {}
+
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       '@babel/runtime': 7.27.6
@@ -6292,6 +7447,10 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      xmlchars: 2.2.0
+
   [email protected]:
     dependencies:
       loose-envify: 1.4.0
@@ -6364,6 +7523,8 @@ snapshots:
       side-channel-map: 1.0.1
       side-channel-weakmap: 1.0.2
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]:
@@ -6388,6 +7549,8 @@ snapshots:
     dependencies:
       stackframe: 1.3.4
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]:
@@ -6401,6 +7564,8 @@ snapshots:
       stack-generator: 2.0.10
       stacktrace-gps: 3.1.2
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       es-errors: 1.3.0
@@ -6482,8 +7647,14 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      js-tokens: 9.0.1
+
   [email protected]([email protected]):
     dependencies:
       client-only: 0.0.1
@@ -6519,6 +7690,8 @@ snapshots:
       csso: 5.0.5
       picocolors: 1.1.1
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       '@alloc/quick-lru': 5.2.0
@@ -6555,6 +7728,12 @@ snapshots:
       mkdirp: 1.0.4
       yallist: 4.0.0
 
+  [email protected]:
+    dependencies:
+      '@istanbuljs/schema': 0.1.3
+      glob: 7.2.3
+      minimatch: 3.1.2
+
   [email protected]: {}
 
   [email protected]:
@@ -6571,6 +7750,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]:
@@ -6578,6 +7759,10 @@ snapshots:
       fdir: 6.4.6([email protected])
       picomatch: 4.0.2
 
+  [email protected]: {}
+
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       is-number: 7.0.0
@@ -6588,6 +7773,17 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      psl: 1.15.0
+      punycode: 2.3.1
+      universalify: 0.2.0
+      url-parse: 1.5.10
+
+  [email protected]:
+    dependencies:
+      punycode: 2.3.1
+
   [email protected]([email protected]):
     dependencies:
       typescript: 5.8.3
@@ -6616,6 +7812,8 @@ snapshots:
     dependencies:
       prelude-ls: 1.2.1
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]: {}
@@ -6668,6 +7866,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       napi-postinstall: 0.3.0
@@ -6702,12 +7902,86 @@ snapshots:
     dependencies:
       punycode: 2.3.1
 
+  [email protected]:
+    dependencies:
+      querystringify: 2.2.0
+      requires-port: 1.0.0
+
   [email protected]([email protected]):
     dependencies:
       react: 18.3.1
 
   [email protected]: {}
 
+  [email protected](@types/[email protected]):
+    dependencies:
+      cac: 6.7.14
+      debug: 4.4.1
+      pathe: 1.1.2
+      picocolors: 1.1.1
+      vite: 5.4.19(@types/[email protected])
+    transitivePeerDependencies:
+      - '@types/node'
+      - less
+      - lightningcss
+      - sass
+      - sass-embedded
+      - stylus
+      - sugarss
+      - supports-color
+      - terser
+
+  [email protected](@types/[email protected]):
+    dependencies:
+      esbuild: 0.21.5
+      postcss: 8.5.6
+      rollup: 4.46.2
+    optionalDependencies:
+      '@types/node': 20.19.7
+      fsevents: 2.3.3
+
+  [email protected](@types/[email protected])(@vitest/[email protected])([email protected]):
+    dependencies:
+      '@vitest/expect': 1.6.1
+      '@vitest/runner': 1.6.1
+      '@vitest/snapshot': 1.6.1
+      '@vitest/spy': 1.6.1
+      '@vitest/utils': 1.6.1
+      acorn-walk: 8.3.4
+      chai: 4.5.0
+      debug: 4.4.1
+      execa: 8.0.1
+      local-pkg: 0.5.1
+      magic-string: 0.30.17
+      pathe: 1.1.2
+      picocolors: 1.1.1
+      std-env: 3.9.0
+      strip-literal: 2.1.1
+      tinybench: 2.9.0
+      tinypool: 0.8.4
+      vite: 5.4.19(@types/[email protected])
+      vite-node: 1.6.1(@types/[email protected])
+      why-is-node-running: 2.3.0
+    optionalDependencies:
+      '@types/node': 20.19.7
+      '@vitest/ui': 1.6.1([email protected])
+      jsdom: 24.1.3
+    transitivePeerDependencies:
+      - less
+      - lightningcss
+      - sass
+      - sass-embedded
+      - stylus
+      - sugarss
+      - supports-color
+      - terser
+
+  [email protected]:
+    dependencies:
+      xml-name-validator: 5.0.0
+
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       '@discoveryjs/json-ext': 0.5.7
@@ -6733,6 +8007,11 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]:
+    dependencies:
+      tr46: 5.1.1
+      webidl-conversions: 7.0.0
+
   [email protected]:
     dependencies:
       is-bigint: 1.1.0
@@ -6778,6 +8057,11 @@ snapshots:
     dependencies:
       isexe: 2.0.0
 
+  [email protected]:
+    dependencies:
+      siginfo: 2.0.0
+      stackback: 0.0.2
+
   [email protected]: {}
 
   [email protected]:
@@ -6796,6 +8080,12 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
+  [email protected]: {}
+
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]: {}
@@ -6809,6 +8099,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       property-expr: 2.0.6
diff --git a/web/web/src/lib/auth/providers/factory.test.js 
b/web/web/src/lib/auth/providers/factory.test.js
new file mode 100644
index 0000000000..3e1ac0855e
--- /dev/null
+++ b/web/web/src/lib/auth/providers/factory.test.js
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
+import { OAuthProviderFactory } from '@/lib/auth/providers/factory'
+
+describe('OAuth Provider Factory', () => {
+  let fetchMock
+  let factory
+
+  // Common mock config
+  const oidcConfig = {
+    'gravitino.authenticator.oauth.provider': 'oidc',
+    'gravitino.authenticator.oauth.authority': 'https://test.example.com',
+    'gravitino.authenticator.oauth.clientId': 'test-client'
+  }
+
+  const mockSuccessResponse = config => ({
+    ok: true,
+    json: async () => config
+  })
+
+  beforeEach(() => {
+    vi.clearAllMocks()
+
+    // Create a fresh factory instance for each test
+    factory = new OAuthProviderFactory()
+
+    // Create a proper fetch mock
+    fetchMock = vi.fn()
+    global.fetch = fetchMock
+  })
+
+  afterEach(() => {
+    vi.restoreAllMocks()
+  })
+
+  describe('getProvider', () => {
+    it('should create OIDC provider when configured', async () => {
+      fetchMock.mockResolvedValueOnce(mockSuccessResponse(oidcConfig))
+
+      const provider = await factory.getProvider()
+
+      expect(provider).toBeDefined()
+      expect(provider.getType()).toBe('oidc')
+      expect(fetchMock).toHaveBeenCalledWith('/configs')
+    })
+
+    it('should create default provider when provider not specified', async () 
=> {
+      // Mock config response without provider config
+      fetchMock.mockResolvedValueOnce({
+        ok: true,
+        json: async () => ({
+          'gravitino.authenticator.oauth.serverUri': 
'https://generic.example.com'
+        })
+      })
+
+      const provider = await factory.getProvider()
+
+      expect(provider).toBeDefined()
+      expect(provider.getType()).toBe('default')
+    })
+
+    it('should return cached provider on subsequent calls', async () => {
+      fetchMock.mockResolvedValueOnce({
+        ok: true,
+        json: async () => ({
+          'gravitino.authenticator.oauth.provider': 'oidc',
+          'gravitino.authenticator.oauth.authority': 
'https://test.example.com',
+          'gravitino.authenticator.oauth.clientId': 'test-client'
+        })
+      })
+
+      const provider1 = await factory.getProvider()
+      const provider2 = await factory.getProvider()
+
+      expect(provider1).toBe(provider2)
+      expect(fetchMock).toHaveBeenCalledTimes(1)
+    })
+
+    it('should handle config fetch errors', async () => {
+      fetchMock.mockRejectedValueOnce(new Error('Network error'))
+
+      await expect(factory.getProvider()).rejects.toThrow('Network error')
+    })
+
+    it('should handle non-ok HTTP responses', async () => {
+      fetchMock.mockResolvedValueOnce({
+        ok: false,
+        status: 500,
+        statusText: 'Internal Server Error'
+      })
+
+      await expect(factory.getProvider()).rejects.toThrow('Failed to fetch 
OAuth config: 500')
+    })
+
+    it('should handle invalid JSON responses', async () => {
+      fetchMock.mockResolvedValueOnce({
+        ok: true,
+        json: async () => {
+          throw new Error('Invalid JSON')
+        }
+      })
+
+      await expect(factory.getProvider()).rejects.toThrow('Invalid JSON')
+    })
+  })
+
+  describe('provider creation', () => {
+    it('should create OIDC provider when provider is set to oidc', async () => 
{
+      fetchMock.mockResolvedValueOnce({
+        ok: true,
+        json: async () => ({
+          'gravitino.authenticator.oauth.provider': 'OIDC',
+          'gravitino.authenticator.oauth.authority': 
'https://oidc.example.com',
+          'gravitino.authenticator.oauth.clientId': 'oidc-client'
+        })
+      })
+
+      const provider = await factory.getProvider()
+
+      expect(provider.getType()).toBe('oidc')
+    })
+
+    it('should use default provider when no provider specified', async () => {
+      fetchMock.mockResolvedValueOnce({
+        ok: true,
+        json: async () => ({
+          'gravitino.authenticator.oauth.serverUri': 
'https://generic.example.com'
+        })
+      })
+
+      const provider = await factory.getProvider()
+
+      expect(provider.getType()).toBe('default')
+    })
+
+    it('should use default provider for unknown provider types', async () => {
+      fetchMock.mockResolvedValueOnce({
+        ok: true,
+        json: async () => ({
+          'gravitino.authenticator.oauth.provider': 'unknown-provider',
+          'gravitino.authenticator.oauth.serverUri': 
'https://generic.example.com'
+        })
+      })
+
+      const provider = await factory.getProvider()
+
+      expect(provider.getType()).toBe('default')
+    })
+  })
+
+  describe('utility methods', () => {
+    it('should get access token from provider', async () => {
+      fetchMock.mockResolvedValueOnce({
+        ok: true,
+        json: async () => ({
+          'gravitino.authenticator.oauth.provider': 'oidc',
+          'gravitino.authenticator.oauth.authority': 
'https://test.example.com',
+          'gravitino.authenticator.oauth.clientId': 'test-client'
+        })
+      })
+
+      // Mock the provider's getAccessToken method
+      const mockToken = 'test-token'
+      const provider = await factory.getProvider()
+      vi.spyOn(provider, 'getAccessToken').mockResolvedValue(mockToken)
+
+      const token = await factory.getAccessToken()
+
+      expect(token).toBe(mockToken)
+    })
+
+    it('should get provider type', async () => {
+      fetchMock.mockResolvedValueOnce({
+        ok: true,
+        json: async () => ({
+          'gravitino.authenticator.oauth.provider': 'oidc',
+          'gravitino.authenticator.oauth.authority': 
'https://test.example.com',
+          'gravitino.authenticator.oauth.clientId': 'test-client'
+        })
+      })
+
+      const providerType = await factory.getProviderType()
+
+      expect(providerType).toBe('oidc')
+    })
+  })
+})
diff --git a/web/web/src/lib/auth/providers/oidc.test.js 
b/web/web/src/lib/auth/providers/oidc.test.js
new file mode 100644
index 0000000000..cffe8bcbc2
--- /dev/null
+++ b/web/web/src/lib/auth/providers/oidc.test.js
@@ -0,0 +1,312 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { describe, it, expect, vi, beforeEach } from 'vitest'
+import { OidcOAuthProvider } from '@/lib/auth/providers/oidc'
+import { UserManager } from 'oidc-client-ts'
+
+// Mock oidc-client-ts
+vi.mock('oidc-client-ts', () => ({
+  UserManager: vi.fn(),
+  WebStorageStateStore: vi.fn()
+}))
+
+describe('OidcOAuthProvider', () => {
+  let provider
+  let mockUserManager
+
+  beforeEach(() => {
+    // Reset all mocks
+    vi.clearAllMocks()
+
+    // Create mock UserManager
+    mockUserManager = {
+      getUser: vi.fn(),
+      signinRedirect: vi.fn(),
+      signinRedirectCallback: vi.fn(),
+      signinSilent: vi.fn(),
+      removeUser: vi.fn()
+    }
+
+    UserManager.mockImplementation(() => mockUserManager)
+
+    provider = new OidcOAuthProvider()
+  })
+
+  describe('initialization', () => {
+    it('should initialize with correct provider type', () => {
+      expect(provider.providerType).toBe('oidc')
+      expect(provider.oidcConfig).toBeNull()
+      expect(provider.userManager).toBeNull()
+    })
+
+    it('should throw error when authority is missing', async () => {
+      const config = {
+        'gravitino.authenticator.oauth.clientId': 'test-client'
+      }
+
+      await expect(provider.initialize(config)).rejects.toThrow(
+        'OIDC provider requires both authority and clientId to be configured'
+      )
+    })
+
+    it('should throw error when clientId is missing', async () => {
+      const config = {
+        'gravitino.authenticator.oauth.authority': 'https://test.example.com'
+      }
+
+      await expect(provider.initialize(config)).rejects.toThrow(
+        'OIDC provider requires both authority and clientId to be configured'
+      )
+    })
+
+    it('should initialize successfully with valid config', async () => {
+      const config = {
+        'gravitino.authenticator.oauth.authority': 'https://test.example.com',
+        'gravitino.authenticator.oauth.clientId': 'test-client',
+        'gravitino.authenticator.oauth.scope': 'openid profile'
+      }
+
+      await provider.initialize(config)
+
+      expect(provider.config).toBe(config)
+      expect(provider.oidcConfig).toEqual({
+        authority: 'https://test.example.com',
+        client_id: 'test-client',
+        response_type: 'code',
+        scope: 'openid profile',
+        redirect_uri: `${window.location.origin}/ui/oauth/callback`,
+        post_logout_redirect_uri: `${window.location.origin}/ui/oauth/logout`,
+        silent_redirect_uri: 
`${window.location.origin}/ui/oauth/silent-callback`,
+        automaticSilentRenew: true,
+        silentRequestTimeout: 10000,
+        userStore: expect.any(Object)
+      })
+      expect(UserManager).toHaveBeenCalledWith(provider.oidcConfig)
+    })
+
+    it('should use default scope when not provided', async () => {
+      const config = {
+        'gravitino.authenticator.oauth.authority': 'https://test.example.com',
+        'gravitino.authenticator.oauth.clientId': 'test-client'
+      }
+
+      await provider.initialize(config)
+
+      expect(provider.oidcConfig.scope).toBe('openid profile email')
+    })
+  })
+
+  describe('getAccessToken', () => {
+    beforeEach(async () => {
+      const config = {
+        'gravitino.authenticator.oauth.authority': 'https://test.example.com',
+        'gravitino.authenticator.oauth.clientId': 'test-client'
+      }
+      await provider.initialize(config)
+    })
+
+    it('should return null when userManager is not available', async () => {
+      provider.userManager = null
+      const token = await provider.getAccessToken()
+      expect(token).toBeNull()
+    })
+
+    it('should return id_token for valid user', async () => {
+      const mockUser = {
+        id_token: 'test-id-token',
+        access_token: 'test-access-token',
+        expired: false
+      }
+      mockUserManager.getUser.mockResolvedValue(mockUser)
+
+      const token = await provider.getAccessToken()
+
+      expect(token).toBe('test-id-token')
+    })
+
+    it('should return access_token when id_token is not available', async () 
=> {
+      const mockUser = {
+        access_token: 'test-access-token',
+        expired: false
+      }
+      mockUserManager.getUser.mockResolvedValue(mockUser)
+
+      const token = await provider.getAccessToken()
+
+      expect(token).toBe('test-access-token')
+    })
+
+    it('should attempt silent refresh for expired user', async () => {
+      const expiredUser = { expired: true }
+
+      const refreshedUser = {
+        id_token: 'new-id-token',
+        expired: false
+      }
+
+      mockUserManager.getUser.mockResolvedValue(expiredUser)
+      mockUserManager.signinSilent.mockResolvedValue(refreshedUser)
+
+      const token = await provider.getAccessToken()
+
+      expect(mockUserManager.signinSilent).toHaveBeenCalled()
+      expect(token).toBe('new-id-token')
+    })
+
+    it('should handle silent refresh failure', async () => {
+      const expiredUser = { expired: true }
+
+      mockUserManager.getUser.mockResolvedValue(expiredUser)
+      mockUserManager.signinSilent.mockRejectedValue(new Error('Refresh 
failed'))
+      mockUserManager.removeUser.mockResolvedValue()
+
+      const token = await provider.getAccessToken()
+
+      expect(mockUserManager.removeUser).toHaveBeenCalled()
+      expect(token).toBeNull()
+    })
+
+    it('should return null for general errors', async () => {
+      mockUserManager.getUser.mockRejectedValue(new Error('General error'))
+
+      const token = await provider.getAccessToken()
+
+      expect(token).toBeNull()
+    })
+  })
+
+  describe('isAuthenticated', () => {
+    beforeEach(async () => {
+      const config = {
+        'gravitino.authenticator.oauth.authority': 'https://test.example.com',
+        'gravitino.authenticator.oauth.clientId': 'test-client'
+      }
+      await provider.initialize(config)
+    })
+
+    it('should return false in server environment', async () => {
+      // Mock server environment
+      const originalWindow = global.window
+      delete global.window
+
+      const isAuth = await provider.isAuthenticated()
+
+      expect(isAuth).toBe(false)
+
+      global.window = originalWindow
+    })
+
+    it('should return true for valid user', async () => {
+      const mockUser = { expired: false }
+      mockUserManager.getUser.mockResolvedValue(mockUser)
+
+      const isAuth = await provider.isAuthenticated()
+
+      expect(isAuth).toBe(true)
+    })
+
+    it('should return false for expired user', async () => {
+      const mockUser = { expired: true }
+      mockUserManager.getUser.mockResolvedValue(mockUser)
+
+      const isAuth = await provider.isAuthenticated()
+
+      expect(isAuth).toBe(false)
+    })
+
+    it('should return false when no user', async () => {
+      mockUserManager.getUser.mockResolvedValue(null)
+
+      const isAuth = await provider.isAuthenticated()
+
+      expect(isAuth).toBe(false)
+    })
+  })
+
+  describe('getUserProfile', () => {
+    beforeEach(async () => {
+      const config = {
+        'gravitino.authenticator.oauth.authority': 'https://test.example.com',
+        'gravitino.authenticator.oauth.clientId': 'test-client'
+      }
+      await provider.initialize(config)
+    })
+
+    it('should return user profile when available', async () => {
+      const mockProfile = { sub: 'user-id', name: 'Test User' }
+      const mockUser = { profile: mockProfile }
+      mockUserManager.getUser.mockResolvedValue(mockUser)
+
+      const profile = await provider.getUserProfile()
+
+      expect(profile).toBe(mockProfile)
+    })
+
+    it('should return null when no user', async () => {
+      mockUserManager.getUser.mockResolvedValue(null)
+
+      const profile = await provider.getUserProfile()
+
+      expect(profile).toBeNull()
+    })
+  })
+
+  describe('clearAuthData', () => {
+    beforeEach(async () => {
+      const config = {
+        'gravitino.authenticator.oauth.authority': 'https://test.example.com',
+        'gravitino.authenticator.oauth.clientId': 'test-client'
+      }
+      await provider.initialize(config)
+    })
+
+    it('should call removeUser on userManager', async () => {
+      mockUserManager.removeUser.mockResolvedValue()
+
+      await provider.clearAuthData()
+
+      expect(mockUserManager.removeUser).toHaveBeenCalled()
+    })
+
+    it('should handle errors silently', async () => {
+      mockUserManager.removeUser.mockRejectedValue(new Error('Remove failed'))
+
+      await expect(provider.clearAuthData()).resolves.not.toThrow()
+    })
+  })
+
+  describe('utility methods', () => {
+    beforeEach(async () => {
+      const config = {
+        'gravitino.authenticator.oauth.authority': 'https://test.example.com',
+        'gravitino.authenticator.oauth.clientId': 'test-client'
+      }
+      await provider.initialize(config)
+    })
+
+    it('should return userManager instance', () => {
+      expect(provider.getUserManager()).toBe(mockUserManager)
+    })
+
+    it('should return oidc config', () => {
+      expect(provider.getOidcConfig()).toBe(provider.oidcConfig)
+    })
+  })
+})
diff --git a/web/web/src/test/setup.js b/web/web/src/test/setup.js
new file mode 100644
index 0000000000..c15d1a7a12
--- /dev/null
+++ b/web/web/src/test/setup.js
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// Mock window.location - Required for OIDC redirect URI construction
+Object.defineProperty(window, 'location', {
+  value: {
+    href: 'http://localhost:3000',
+    origin: 'http://localhost:3000',
+    pathname: '/',
+    search: '',
+    hash: ''
+  },
+  writable: true
+})
diff --git a/web/web/vitest.config.js b/web/web/vitest.config.js
new file mode 100644
index 0000000000..4c0a75fde3
--- /dev/null
+++ b/web/web/vitest.config.js
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { defineConfig } from 'vitest/config'
+import { resolve } from 'path'
+
+export default defineConfig({
+  test: {
+    globals: true,
+    environment: 'jsdom',
+    setupFiles: ['./src/test/setup.js'],
+    include: ['src/**/*.{test,spec}.{js,ts,jsx,tsx}'],
+    exclude: ['node_modules', 'dist', '.next'],
+    coverage: {
+      provider: 'v8',
+      reporter: ['text', 'json', 'html'],
+      exclude: [
+        'node_modules/',
+        'src/test/',
+        '**/*.config.js',
+        '**/*.d.ts',
+        'coverage/**',
+        '.next/**',
+        'src/app/**',
+        'src/components/**',
+        'src/lib/icons/**'
+      ]
+    }
+  },
+  resolve: {
+    alias: {
+      '@': resolve(__dirname, './src')
+    }
+  }
+})

Reply via email to