diff --git a/.github/workflows/actions/cache-deps/action.yml b/.github/workflows/actions/cache-deps/action.yml new file mode 100644 index 0000000..8e7bc4b --- /dev/null +++ b/.github/workflows/actions/cache-deps/action.yml @@ -0,0 +1,42 @@ +name: 'Setup Node and pnpm and cache dependencies' +description: 'an action to setup node, pnpm and cache dependencies for workflows' +inputs: + caching: + description: "Whether to cache dependencies" + required: false + default: "true" +outputs: + used-cache: + description: "Whether the cache was used" + value: ${{steps.install-deps.outputs.cache}} +runs: + using: 'composite' + steps: + + - name: Set up Node.js + uses: actions/setup-node@v6 + with: + node-version: '20' + + - name: Cache Dependencies + if: ${{inputs.caching == 'true'}} + id: cache + uses: actions/cache@v4 + with: + path: ~/.pnpm-store + key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm- + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10.7.1 + + - name: Install dependencies + id: install-deps + if: ${{steps.cache.outputs.cache-hit != 'true'}} || ${{inputs.caching == 'false'}} + run: | + pnpm install + echo "cache=${{inputs.caching}}" >> $GITHUB_OUTPUT + shell: bash \ No newline at end of file diff --git a/.github/workflows/actions/e2e-tests/action.yml b/.github/workflows/actions/e2e-tests/action.yml new file mode 100644 index 0000000..3ee9f73 --- /dev/null +++ b/.github/workflows/actions/e2e-tests/action.yml @@ -0,0 +1,64 @@ +name: 'E2E Tests' +description: 'Run end-to-end tests with Cypress' + +inputs: + database-url: + description: 'Database connection URL' + required: true + better-auth-secret: + description: 'Better Auth secret key' + required: true + better-auth-url: + description: 'Better Auth URL' + required: false + default: 'http://localhost:3000' + better-auth-trusted-origins: + description: 'Better Auth trusted origins' + required: false + default: 'http://localhost:3000,http://127.0.0.1:3000' + resend-api-key: + description: 'Resend API key' + required: true + base-url: + description: 'Base URL for the application' + required: false + default: 'http://localhost:3000' + prod-base-url: + description: 'Production base URL' + required: true + test-email: + description: 'Test user email' + required: true + test-password: + description: 'Test user password' + required: true + +runs: + using: 'composite' + steps: + - name: Install Cypress + shell: bash + run: pnpm add cypress --save-dev && pnpm cypress install + + - name: Run E2E Tests + shell: bash + env: + DATABASE_URL: ${{ inputs.database-url }} + BETTER_AUTH_SECRET: ${{ inputs.better-auth-secret }} + BETTER_AUTH_URL: ${{ inputs.better-auth-url }} + BETTER_AUTH_TRUSTED_ORIGINS: ${{ inputs.better-auth-trusted-origins }} + RESEND_API_KEY: ${{ inputs.resend-api-key }} + BASE_URL: ${{ inputs.base-url }} + PROD_BASE_URL: ${{ inputs.prod-base-url }} + TEST_EMAIL: ${{ inputs.test-email }} + TEST_PASSWORD: ${{ inputs.test-password }} + run: pnpm dlx start-server-and-test "pnpm dev" http://localhost:3000 "pnpm cypress run --browser chrome" + + - name: Upload Cypress Videos and Screenshots on Failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: cypress-artifacts + path: | + cypress/videos + cypress/screenshots \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..5d59665 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,101 @@ +name: "CI Pipeline" +on: + push: + branches: + [main] + pull_request: + branches: + [main] + +jobs: + tests: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Load & Cache Dependencies + id: load-cache-deps + uses: ./.github/workflows/actions/cache-deps + with: + caching: "true" + - name: Output Cache Status + run: echo "Used cache ${{steps.load-cache-deps.outputs.used-cache}}" + - name: Run Unit Tests + env: + DATABASE_URL: ${{ secrets.DATABASE_URL }} + BETTER_AUTH_SECRET: ${{ secrets.BETTER_AUTH_SECRET }} + BETTER_AUTH_URL: http://localhost:3000 + BETTER_AUTH_TRUSTED_ORIGINS: "http://localhost:3000,http://127.0.0.1:3000" + RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }} + BASE_URL: http://localhost:3000 + PROD_BASE_URL: ${{ secrets.PROD_BASE_URL }} + run: pnpm test + e2e-tests: + needs: tests + runs-on: ubuntu-latest + timeout-minutes: 25 + container: + image: cypress/browsers:latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Load & Cache Dependencies + id: load-cache-deps + uses: ./.github/workflows/actions/cache-deps + with: + caching: "true" + - name: Output Cache Status + run: echo "Used cache ${{steps.load-cache-deps.outputs.used-cache}}" + - name: Run E2E Tests + uses: ./.github/workflows/actions/e2e-tests + with: + database-url: ${{ secrets.DATABASE_URL }} + better-auth-secret: ${{ secrets.BETTER_AUTH_SECRET }} + resend-api-key: ${{ secrets.RESEND_API_KEY }} + prod-base-url: ${{ secrets.PROD_BASE_URL }} + test-email: ${{ secrets.TEST_EMAIL }} + test-password: ${{ secrets.TEST_PASSWORD }} + + lint: + needs: [tests, e2e-tests] + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Load & Cache Dependencies + id: load-cache-deps + uses: ./.github/workflows/actions/cache-deps + with: + caching: "true" + - name: Output Cache Status + run: echo "Used cache ${{steps.load-cache-deps.outputs.used-cache}}" + - name: Run Linter + run: pnpm lint + - name: Lint Status + run: echo "Linting completed successfully" + build: + needs: [tests, lint, e2e-tests] + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Load & Cache Dependencies + id: load-cache-deps + uses: ./.github/workflows/actions/cache-deps + with: + caching: "true" + - name: Output Cache Status + run: echo "Used cache ${{steps.load-cache-deps.outputs.used-cache}}" + - name: Build Project + env: + DATABASE_URL: ${{ secrets.DATABASE_URL }} + BETTER_AUTH_SECRET: ${{ secrets.BETTER_AUTH_SECRET }} + BETTER_AUTH_URL: http://localhost:3000 + BETTER_AUTH_TRUSTED_ORIGINS: "http://localhost:3000,http://127.0.0.1:3000" + RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }} + BASE_URL: http://localhost:3000 + PROD_BASE_URL: ${{ secrets.PROD_BASE_URL }} + run: pnpm build + - name: Build Status + run: echo "Build completed successfully" + diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml deleted file mode 100644 index 39d06b1..0000000 --- a/.github/workflows/run-tests.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: e2e-tests - -on: - push: - branches: [main] - pull_request: - branches: [main] - -permissions: - contents: read -env: - DATABASE_URL: ${{ secrets.DATABASE_URL }} - BETTER_AUTH_SECRET: ${{ secrets.BETTER_AUTH_SECRET }} - BETTER_AUTH_URL: http://localhost:3000 - BETTER_AUTH_TRUSTED_ORIGINS: "http://localhost:3000,http://127.0.0.1:3000" - RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }} - BASE_URL: ${{ secrets.BASE_URL }} - PROD_BASE_URL: ${{ secrets.PROD_BASE_URL }} -jobs: - dashboard-e2e-tests: - runs-on: ubuntu-latest - timeout-minutes: 25 - container: - image: cypress/browsers - steps: - - name: Get Code - uses: actions/checkout@v6 - - name: Cache Dependencies - uses: actions/cache@v4 - with: - path: ~/.pnpm-store - key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm- - - name: Install Dependencies with pnpm - uses: pnpm/action-setup@v4 - with: - version: 10.7.1 - - - name: Install Packages - run: pnpm install - - - name: Install Cypress - run: pnpm add cypress --save-dev && pnpm cypress install - - - name: Run E2E Tests - env: - TEST_EMAIL: ${{ secrets.TEST_EMAIL }} - TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }} - - run: pnpm dlx start-server-and-test "pnpm dev" http://localhost:3000 "pnpm cypress run" - build: - needs: dashboard-e2e-tests - runs-on: ubuntu-latest - steps: - - name: Get Code - uses: actions/checkout@v6 - - name: Cache Dependencies - uses: actions/cache@v4 - with: - path: ~/.pnpm-store - key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm- - - name: Install Dependencies with pnpm - uses: pnpm/action-setup@v4 - with: - version: 10.7.1 - - - name: Install Packages - run: pnpm install - - name: Get Build - run: pnpm build diff --git a/.gitignore b/.gitignore index 5ef6a52..6633467 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts +cypress/downloads \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f030bdd --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "cSpell.words": [ + "gsap", + "oklch" + ] +} \ No newline at end of file diff --git a/components.json b/components.json index edcaef2..8019f36 100644 --- a/components.json +++ b/components.json @@ -18,5 +18,7 @@ "lib": "@/lib", "hooks": "@/hooks" }, - "registries": {} + "registries": { + "@react-bits": "https://reactbits.dev/r/{name}.json" + } } diff --git a/cypress/e2e/Signup.cy.ts b/cypress/e2e/Signup.cy.ts index 3b8c8e4..e315b30 100644 --- a/cypress/e2e/Signup.cy.ts +++ b/cypress/e2e/Signup.cy.ts @@ -1,58 +1,58 @@ -import { faker } from '@faker-js/faker'; +import { faker } from "@faker-js/faker"; -describe('The Sign Up Form Test Suites', () => { +describe("The Sign Up Form Test Suites", () => { const randomEmail = faker.internet.email(); beforeEach(() => { - cy.visit('/sign-up'); + cy.visit("/sign-up"); }); - it('should display validation errors for each required field when submitting empty form', () => { - cy.step('Submit the empty sign-up form'); - cy.getTestById('submit-button').click(); - cy.step('Check for validation error messages for each required field'); - cy.getTestById('name-error').should( - 'contain.text', - 'Name must be at least 2 characters' + it("should display validation errors for each required field when submitting empty form", () => { + cy.step("Submit the empty sign-up form"); + cy.getTestById("submit-button").click(); + cy.step("Check for validation error messages for each required field"); + cy.getTestById("name-error").should( + "contain.text", + "Name must be at least 2 characters" ); - cy.getTestById('email-error').should( - 'contain.text', - 'Invalid email address' + cy.getTestById("email-error").should( + "contain.text", + "Invalid email address" ); - cy.getTestById('password-error').then(($error) => { + cy.getTestById("password-error").then(($error) => { expect($error.text()).to.equal( - 'Password must be at least 4 characters long, Password must contain at least one letter and one number' + "Password must be at least 4 characters long, Password must contain at least one letter and one number" ); }); }); - it('should give an error for already registered email', () => { - cy.step('Fill the sign-up form with an already registered email'); - cy.getTestById('name-input').type('Existing User'); - cy.getTestById('email-input').type('hibrahim.celik@yahoo.com'); - cy.getTestById('password-input').type('Test1234'); - cy.getTestById('confirm-password-input').type('Test1234'); - cy.step('Submit the sign-up form'); - cy.getTestById('submit-button').click(); - cy.step('Check for email already registered error message'); - cy.getTestById('email-error').should( - 'contain.text', - 'User already exists. Use another email.' + it("should give an error for already registered email", () => { + cy.step("Fill the sign-up form with an already registered email"); + cy.getTestById("name-input").type("Existing User"); + cy.getTestById("email-input").type(Cypress.env("TEST_EMAIL")); + cy.getTestById("password-input").type("Test1234"); + cy.getTestById("confirm-password-input").type("Test1234"); + cy.step("Submit the sign-up form"); + cy.getTestById("submit-button").click(); + cy.step("Check for email already registered error message"); + cy.getTestById("email-error").should( + "contain.text", + "User already exists. Use another email." ); }); - it.skip('should show a toast notification upon succesful signup', () => { - cy.step('Fill the sign-up form with valid and unique data'); + it.skip("should show a toast notification upon succesful signup", () => { + cy.step("Fill the sign-up form with valid and unique data"); - cy.fixture('example').then((user) => { - cy.getTestById('name-input').type(user.name); - cy.getTestById('email-input').type(randomEmail); - cy.getTestById('password-input').type(user.password); - cy.getTestById('confirm-password-input').type(user.password); + cy.fixture("example").then((user) => { + cy.getTestById("name-input").type(user.name); + cy.getTestById("email-input").type(randomEmail); + cy.getTestById("password-input").type(user.password); + cy.getTestById("confirm-password-input").type(user.password); }); - cy.step('Submit the sign-up form'); - cy.getTestById('submit-button').click(); - cy.step('Check for success toast notification'); - cy.get('div[data-title]').should( - 'contain.text', - 'Your account has been Created. Please check your email to verify it.' + cy.step("Submit the sign-up form"); + cy.getTestById("submit-button").click(); + cy.step("Check for success toast notification"); + cy.get("div[data-title]").should( + "contain.text", + "Your account has been Created. Please check your email to verify it." ); }); }); diff --git a/eslint.config.mjs b/eslint.config.mjs index 719cea2..dbc41bf 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -11,6 +11,14 @@ const compat = new FlatCompat({ const eslintConfig = [ ...compat.extends("next/core-web-vitals", "next/typescript"), + { + rules: { + "@typescript-eslint/ban-ts-comment": ["error", { + "ts-nocheck": false, + }], + "@typescript-eslint/no-unused-expressions": "off", + }, + }, { ignores: [ "node_modules/**", @@ -18,6 +26,7 @@ const eslintConfig = [ "out/**", "build/**", "next-env.d.ts", + "coverage/**", ], }, ]; diff --git a/package.json b/package.json index aed28b0..75ef7b6 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,15 @@ "build": "next build", "start": "next start", "lint": "eslint", + "test": "vitest", + "coverage": "vitest run --coverage", "db:generate": "drizzle-kit generate --schema ./src/db/schema.ts --out=./src/db/migrations --dialect postgresql", "db:push": "drizzle-kit push", "db:migrate": "drizzle-kit migrate", "db:studio": "drizzle-kit studio", "db:seed": "tsx src/db/seed.ts", - "cy:open": "cypress open" + "cy:open": "cypress open", + "cy:run": "cypress run --browser chrome" }, "dependencies": { "@neondatabase/serverless": "^1.0.2", @@ -41,9 +44,11 @@ "cypress-plugin-xhr-toggle": "^1.2.1", "date-fns": "^4.1.0", "drizzle-orm": "^0.44.6", + "gsap": "^3.14.2", "lucide-react": "^0.544.0", - "motion": "^12.23.22", + "motion": "^12.23.12", "next": "15.5.4", + "next-router-mock": "^1.0.4", "next-themes": "^0.4.6", "nextjs-toploader": "^3.9.17", "react": "19.1.0", @@ -60,20 +65,30 @@ "@eslint/eslintrc": "^3", "@faker-js/faker": "^10.1.0", "@tailwindcss/postcss": "^4", + "@testing-library/dom": "^10.4.1", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.1", + "@testing-library/user-event": "^14.6.1", "@types/cypress-dotenv": "^3.0.0", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", + "@types/testing-library__jest-dom": "^6.0.0", + "@vitejs/plugin-react": "^5.1.2", + "@vitest/coverage-v8": "4.0.16", "cypress": "^15.5.0", "cypress-dotenv": "^3.0.1", "dotenv": "^17.2.3", "drizzle-kit": "^0.31.5", "eslint": "^9", "eslint-config-next": "15.5.4", + "jsdom": "^27.3.0", "shadcn": "^3.3.1", "tailwindcss": "^4", "tsx": "^4.20.6", "tw-animate-css": "^1.4.0", - "typescript": "^5" + "typescript": "^5", + "vite-tsconfig-paths": "^6.0.1", + "vitest": "^4.0.16" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e53de86..4a7a606 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -86,15 +86,21 @@ importers: drizzle-orm: specifier: ^0.44.6 version: 0.44.6(@neondatabase/serverless@1.0.2)(@types/pg@8.15.5)(kysely@0.28.7) + gsap: + specifier: ^3.14.2 + version: 3.14.2 lucide-react: specifier: ^0.544.0 version: 0.544.0(react@19.1.0) motion: - specifier: ^12.23.22 + specifier: ^12.23.12 version: 12.23.22(react-dom@19.1.0(react@19.1.0))(react@19.1.0) next: specifier: 15.5.4 version: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next-router-mock: + specifier: ^1.0.4 + version: 1.0.4(next@15.5.4(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -138,6 +144,18 @@ importers: '@tailwindcss/postcss': specifier: ^4 version: 4.1.14 + '@testing-library/dom': + specifier: ^10.4.1 + version: 10.4.1 + '@testing-library/jest-dom': + specifier: ^6.9.1 + version: 6.9.1 + '@testing-library/react': + specifier: ^16.3.1 + version: 16.3.1(@testing-library/dom@10.4.1)(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@testing-library/user-event': + specifier: ^14.6.1 + version: 14.6.1(@testing-library/dom@10.4.1) '@types/cypress-dotenv': specifier: ^3.0.0 version: 3.0.0(dotenv@17.2.3) @@ -150,6 +168,15 @@ importers: '@types/react-dom': specifier: ^19 version: 19.2.0(@types/react@19.2.0) + '@types/testing-library__jest-dom': + specifier: ^6.0.0 + version: 6.0.0 + '@vitejs/plugin-react': + specifier: ^5.1.2 + version: 5.1.2(vite@7.3.0(@types/node@20.19.19)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6)) + '@vitest/coverage-v8': + specifier: 4.0.16 + version: 4.0.16(vitest@4.0.16(@types/node@20.19.19)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.1)(msw@2.11.3(@types/node@20.19.19)(typescript@5.9.3))(tsx@4.20.6)) cypress: specifier: ^15.5.0 version: 15.5.0 @@ -168,6 +195,9 @@ importers: eslint-config-next: specifier: 15.5.4 version: 15.5.4(eslint@9.36.0(jiti@2.6.1))(typescript@5.9.3) + jsdom: + specifier: ^27.3.0 + version: 27.3.0(postcss@8.5.6) shadcn: specifier: ^3.3.1 version: 3.3.1(@types/node@20.19.19)(typescript@5.9.3) @@ -183,9 +213,21 @@ importers: typescript: specifier: ^5 version: 5.9.3 + vite-tsconfig-paths: + specifier: ^6.0.1 + version: 6.0.1(typescript@5.9.3)(vite@7.3.0(@types/node@20.19.19)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6)) + vitest: + specifier: ^4.0.16 + version: 4.0.16(@types/node@20.19.19)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.1)(msw@2.11.3(@types/node@20.19.19)(typescript@5.9.3))(tsx@4.20.6) packages: + '@acemir/cssom@0.9.29': + resolution: {integrity: sha512-G90x0VW+9nW4dFajtjCoT+NM0scAfH9Mb08IcjgFHYbfiL/lU04dTF9JuVOi3/OH+DJCQdcIseSXkdCB9Ky6JA==} + + '@adobe/css-tools@4.4.4': + resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -194,6 +236,15 @@ packages: resolution: {integrity: sha512-9q/yCljni37pkMr4sPrI3G4jqdIk074+iukc5aFJl7kmDCCsiJrbZ6zKxnES1Gwg+i9RcDZwvktl23puGslmvA==} hasBin: true + '@asamuzakjp/css-color@4.1.1': + resolution: {integrity: sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==} + + '@asamuzakjp/dom-selector@6.7.6': + resolution: {integrity: sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==} + + '@asamuzakjp/nwsapi@2.3.9': + resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} @@ -206,10 +257,18 @@ packages: resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} engines: {node: '>=6.9.0'} + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.28.3': resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} engines: {node: '>=6.9.0'} + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} @@ -268,6 +327,10 @@ packages: resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.27.1': resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} @@ -281,6 +344,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-syntax-jsx@7.27.1': resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} engines: {node: '>=6.9.0'} @@ -299,6 +367,18 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-typescript@7.28.0': resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==} engines: {node: '>=6.9.0'} @@ -323,10 +403,22 @@ packages: resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + '@babel/types@7.28.4': resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + '@better-auth/core@1.3.26': resolution: {integrity: sha512-S5ooXaOcn9eLV3/JayfbMsAB5PkfoTRaRrtpb5djwvI/UAJOgLyjqhd+rObsBycovQ/nPQvMKjzyM/G1oBKngA==} @@ -342,6 +434,40 @@ packages: '@bundled-es-modules/statuses@1.0.1': resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + 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/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-syntax-patches-for-csstree@1.0.14': + resolution: {integrity: sha512-zSlIxa20WvMojjpCSy8WrNpcZ61RqfTfX3XTaOeVlGJrt/8HF3YbzgFZa01yTbT4GWQLwfTcC3EB8i3XnB647Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + '@cypress/request@3.0.9': resolution: {integrity: sha512-I3l7FdGRXluAS44/0NguwWlO83J18p0vlr2FYHrJkWdNYhgVoiYo61IXPqaOsL+vNxU1ZqMACzItGK3/KKDsdw==} engines: {node: '>= 6'} @@ -388,6 +514,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.27.1': + resolution: {integrity: sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.18.20': resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -400,6 +532,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.27.1': + resolution: {integrity: sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.18.20': resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} @@ -412,6 +550,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.27.1': + resolution: {integrity: sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.18.20': resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -424,6 +568,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.27.1': + resolution: {integrity: sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.18.20': resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -436,6 +586,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.27.1': + resolution: {integrity: sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.18.20': resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -448,6 +604,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.27.1': + resolution: {integrity: sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.18.20': resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -460,6 +622,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.27.1': + resolution: {integrity: sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.18.20': resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -472,6 +640,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.27.1': + resolution: {integrity: sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.18.20': resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -484,6 +658,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.27.1': + resolution: {integrity: sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.18.20': resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -496,6 +676,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.27.1': + resolution: {integrity: sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.18.20': resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -508,6 +694,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.27.1': + resolution: {integrity: sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.18.20': resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -520,6 +712,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.27.1': + resolution: {integrity: sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.18.20': resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -532,6 +730,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.27.1': + resolution: {integrity: sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.18.20': resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -544,6 +748,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.27.1': + resolution: {integrity: sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.18.20': resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -556,6 +766,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.27.1': + resolution: {integrity: sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.18.20': resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -568,6 +784,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.27.1': + resolution: {integrity: sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.18.20': resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} @@ -580,12 +802,24 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.27.1': + resolution: {integrity: sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.10': resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.27.1': + resolution: {integrity: sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.18.20': resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -598,12 +832,24 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.27.1': + resolution: {integrity: sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.10': resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.27.1': + resolution: {integrity: sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.18.20': resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -616,12 +862,24 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.27.1': + resolution: {integrity: sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.10': resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.27.1': + resolution: {integrity: sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.18.20': resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -634,6 +892,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.27.1': + resolution: {integrity: sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.18.20': resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} @@ -646,6 +910,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.27.1': + resolution: {integrity: sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.18.20': resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -658,6 +928,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.27.1': + resolution: {integrity: sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.18.20': resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -670,6 +946,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.27.1': + resolution: {integrity: sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.9.0': resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1477,6 +1759,119 @@ packages: react: ^18.0 || ^19.0 || ^19.0.0-rc react-dom: ^18.0 || ^19.0 || ^19.0.0-rc + '@rolldown/pluginutils@1.0.0-beta.53': + resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} + + '@rollup/rollup-android-arm-eabi@4.53.5': + resolution: {integrity: sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.53.5': + resolution: {integrity: sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.53.5': + resolution: {integrity: sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.53.5': + resolution: {integrity: sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.53.5': + resolution: {integrity: sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.53.5': + resolution: {integrity: sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.53.5': + resolution: {integrity: sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.53.5': + resolution: {integrity: sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.53.5': + resolution: {integrity: sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.53.5': + resolution: {integrity: sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.53.5': + resolution: {integrity: sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.53.5': + resolution: {integrity: sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.53.5': + resolution: {integrity: sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.53.5': + resolution: {integrity: sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.53.5': + resolution: {integrity: sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.53.5': + resolution: {integrity: sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.53.5': + resolution: {integrity: sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.53.5': + resolution: {integrity: sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.53.5': + resolution: {integrity: sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.53.5': + resolution: {integrity: sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.53.5': + resolution: {integrity: sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.53.5': + resolution: {integrity: sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==} + cpu: [x64] + os: [win32] + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -1500,6 +1895,9 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} @@ -1610,6 +2008,35 @@ packages: resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==} engines: {node: '>=12'} + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/react@16.3.1': + resolution: {integrity: sha512-gr4KtAWqIOQoucWYD/f6ki+j5chXfcPc74Col/6poTyqTmn7zRmodWahWRCp8tYd+GMqBonw6hstNzqjbs6gjw==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + '@trpc/client@11.7.0': resolution: {integrity: sha512-VLMoA9KUIItrD/tXKLw2Hvu71V7cRMBNQhXbmm5weSkFVWdAGwLXzV5f85QPdOM8669dD+a1QbGJCK0LNBPbgQ==} peerDependencies: @@ -1647,6 +2074,24 @@ packages: '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} @@ -1682,6 +2127,9 @@ packages: '@types/d3-timer@3.0.2': resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -1717,6 +2165,10 @@ packages: '@types/statuses@2.0.6': resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} + '@types/testing-library__jest-dom@6.0.0': + resolution: {integrity: sha512-bnreXCgus6IIadyHNlN/oI5FfX4dWgvGhOPvpr7zzCYDGAPIfvyIoAozMBINmhmsVuqV0cncejF2y5KC7ScqOg==} + deprecated: This is a stub types definition. @testing-library/jest-dom provides its own type definitions, so you do not need this installed. + '@types/tmp@0.2.6': resolution: {integrity: sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==} @@ -1877,6 +2329,50 @@ packages: cpu: [x64] os: [win32] + '@vitejs/plugin-react@5.1.2': + resolution: {integrity: sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + + '@vitest/coverage-v8@4.0.16': + resolution: {integrity: sha512-2rNdjEIsPRzsdu6/9Eq0AYAzYdpP6Bx9cje9tL3FE5XzXRQF1fNU9pe/1yE8fCrS0HD+fBtt6gLPh6LI57tX7A==} + peerDependencies: + '@vitest/browser': 4.0.16 + vitest: 4.0.16 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@4.0.16': + resolution: {integrity: sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==} + + '@vitest/mocker@4.0.16': + resolution: {integrity: sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.0.16': + resolution: {integrity: sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA==} + + '@vitest/runner@4.0.16': + resolution: {integrity: sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q==} + + '@vitest/snapshot@4.0.16': + resolution: {integrity: sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA==} + + '@vitest/spy@4.0.16': + resolution: {integrity: sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw==} + + '@vitest/utils@4.0.16': + resolution: {integrity: sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA==} + accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} @@ -1922,6 +2418,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + ansis@4.2.0: resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} engines: {node: '>=14'} @@ -1936,6 +2436,9 @@ packages: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} @@ -1983,6 +2486,10 @@ packages: resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} engines: {node: '>=0.8'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} @@ -1990,6 +2497,9 @@ packages: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} + ast-v8-to-istanbul@0.3.9: + resolution: {integrity: sha512-dSC6tJeOJxbZrPzPbv5mMd6CMiQ1ugaVXXPRad2fXUSsy1kstFn9XQWemV9VW7Y7kpxgQ/4WMoZfwdH8XSU48w==} + astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -2071,6 +2581,9 @@ packages: better-call@1.0.19: resolution: {integrity: sha512-sI3GcA1SCVa3H+CDHl8W8qzhlrckwXOTKhqq3OOPXjgn5aTOMIqGY34zLY/pHA6tRRMjTUC3lz5Mi7EbDA24Kw==} + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + blob-util@2.0.2: resolution: {integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==} @@ -2139,6 +2652,10 @@ packages: caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + chai@6.2.1: + resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} + engines: {node: '>=18'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -2276,6 +2793,17 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + css-tree@3.1.0: + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + + cssstyle@5.3.4: + resolution: {integrity: sha512-KyOS/kJMEq5O9GdPnaf82noigg5X5DYn0kZPJTaAsCUaBizp6Xa1y9D4Qoqf/JazEXWuruErHgVXwjN5391ZJw==} + engines: {node: '>=20'} + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -2356,6 +2884,10 @@ packages: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} + data-urls@6.0.0: + resolution: {integrity: sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==} + engines: {node: '>=20'} + data-view-buffer@1.0.2: resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} engines: {node: '>= 0.4'} @@ -2397,6 +2929,9 @@ packages: decimal.js-light@2.5.1: resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + dedent@1.7.0: resolution: {integrity: sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==} peerDependencies: @@ -2431,6 +2966,10 @@ packages: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + detect-libc@2.1.1: resolution: {integrity: sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==} engines: {node: '>=8'} @@ -2446,6 +2985,12 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} @@ -2611,6 +3156,10 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -2634,6 +3183,9 @@ packages: resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -2665,6 +3217,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.27.1: + resolution: {integrity: sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -2797,6 +3354,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -2835,6 +3395,10 @@ packages: resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==} engines: {node: '>=4'} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + express-rate-limit@7.5.1: resolution: {integrity: sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==} engines: {node: '>= 16'} @@ -3080,6 +3644,9 @@ packages: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -3094,6 +3661,9 @@ packages: resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + gsap@3.14.2: + resolution: {integrity: sha512-P8/mMxVLU7o4+55+1TCnQrPmgjPKnwkzkXOK1asnR9Jg2lna4tEY5qBJjMmAaOBDDZWtlRjBXjLa0w53G/uBLA==} + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -3128,6 +3698,13 @@ packages: headers-polyfill@4.0.3: resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-to-text@9.0.5: resolution: {integrity: sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==} engines: {node: '>=14'} @@ -3139,6 +3716,10 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + http-signature@1.4.0: resolution: {integrity: sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==} engines: {node: '>=0.10'} @@ -3306,6 +3887,9 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} @@ -3392,6 +3976,22 @@ packages: isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + iterator.prototype@1.1.5: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} @@ -3406,6 +4006,9 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -3413,6 +4016,15 @@ packages: jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + jsdom@27.3.0: + resolution: {integrity: sha512-GtldT42B8+jefDUC4yUKAvsaOrH7PDHmZxZXNgF2xMmymjUbRYJvpAybZAKEmXDGTM0mCsz8duOa4vTm5AY2Kg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -3593,6 +4205,10 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lru-cache@11.2.4: + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -3601,13 +4217,30 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + magic-string@0.30.19: resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.5.1: + resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + mdn-data@2.12.2: + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + media-typer@1.1.0: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} @@ -3651,6 +4284,10 @@ packages: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + minimatch@10.0.3: resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} engines: {node: 20 || >=22} @@ -3731,6 +4368,12 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} + next-router-mock@1.0.4: + resolution: {integrity: sha512-EBOd/J2PxgZ9WH732ppfEojZgSTSOkjEz0DgQn+9c/PELKnc9P19PAcmQUi7fSlk3LAKbMGzl5DEOb40x7l8kA==} + peerDependencies: + next: '>=10.0.0' + react: '>=17.0.0' + next-themes@0.4.6: resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} peerDependencies: @@ -3824,6 +4467,9 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -3884,6 +4530,9 @@ packages: resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} engines: {node: '>=18'} + parse5@8.0.0: + resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==} + parseley@0.12.1: resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==} @@ -3915,6 +4564,9 @@ packages: path-to-regexp@8.3.0: resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + peberminta@0.9.0: resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==} @@ -3995,6 +4647,10 @@ packages: resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} engines: {node: '>=6'} + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-ms@9.3.0: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} @@ -4068,12 +4724,19 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} react-promise-suspense@0.3.4: resolution: {integrity: sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ==} + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + react-remove-scroll-bar@2.3.8: resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} engines: {node: '>=10'} @@ -4134,6 +4797,10 @@ packages: react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} @@ -4152,6 +4819,10 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + resend@6.1.2: resolution: {integrity: sha512-C9Q+YkRe57P8MQlkHG3yatSR/B6sqBGA06Ri2DveJfkz9Vm16182FC/iHB0K6IAfmqZ4yRrFebFw1EPuktLtSg==} engines: {node: '>=18'} @@ -4195,6 +4866,11 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + rollup@4.53.5: + resolution: {integrity: sha512-iTNAbFSlRpcHeeWu73ywU/8KuU/LZmNCSxp6fjQkJBD3ivUb8tpDrXhIxEzA05HlYMEwmtaUnb3RP+YNv162OQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + rou3@0.5.1: resolution: {integrity: sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==} @@ -4226,6 +4902,10 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + scheduler@0.26.0: resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} @@ -4299,6 +4979,9 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -4342,6 +5025,9 @@ packages: stable-hash@0.0.5: resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} @@ -4350,6 +5036,9 @@ packages: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + stdin-discarder@0.2.2: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} @@ -4416,6 +5105,10 @@ packages: resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} engines: {node: '>=18'} + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -4445,6 +5138,9 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + systeminformation@5.27.7: resolution: {integrity: sha512-saaqOoVEEFaux4v0K8Q7caiauRwjXC4XbD2eH60dxHXbpKxQ8kH9Rf7Jh+nryKpOUSEFxtCdBlSUx0/lO6rwRg==} engines: {node: '>=8.0.0'} @@ -4474,13 +5170,24 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinyexec@1.0.1: resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} + tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} @@ -4515,6 +5222,10 @@ packages: resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} engines: {node: '>=16'} + tr46@6.0.0: + resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} + engines: {node: '>=20'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -4528,6 +5239,16 @@ packages: ts-morph@26.0.0: resolution: {integrity: sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==} + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -4676,10 +5397,112 @@ packages: victory-vendor@36.9.2: resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + vite-tsconfig-paths@6.0.1: + resolution: {integrity: sha512-OQuYkfCQhc2T+n//0N7/oogTosgiSyZQ7dydrpUlH5SbnFTtplpekdY4GMi6jDwEpiwWlqeUJMyPfC2ePM1+2A==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + + vite@7.3.0: + resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.0.16: + resolution: {integrity: sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.16 + '@vitest/browser-preview': 4.0.16 + '@vitest/browser-webdriverio': 4.0.16 + '@vitest/ui': 4.0.16 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} + webidl-conversions@8.0.0: + resolution: {integrity: sha512-n4W4YFyz5JzOfQeA8oN7dUYpR+MBP3PIUsn2jLjWXwK5ASUzt0Jc/A5sAUZoCYFJRGF0FBKJ+1JjN43rNdsQzA==} + engines: {node: '>=20'} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@15.1.0: + resolution: {integrity: sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==} + engines: {node: '>=20'} + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -4706,6 +5529,11 @@ packages: engines: {node: ^16.13.0 || >=18.0.0} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -4721,6 +5549,25 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.18.3: + 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 + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -4772,6 +5619,10 @@ packages: snapshots: + '@acemir/cssom@0.9.29': {} + + '@adobe/css-tools@4.4.4': {} + '@alloc/quick-lru@5.2.0': {} '@antfu/ni@25.0.0': @@ -4781,6 +5632,24 @@ snapshots: package-manager-detector: 1.3.0 tinyexec: 1.0.1 + '@asamuzakjp/css-color@4.1.1': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + lru-cache: 11.2.4 + + '@asamuzakjp/dom-selector@6.7.6': + dependencies: + '@asamuzakjp/nwsapi': 2.3.9 + bidi-js: 1.0.3 + css-tree: 3.1.0 + is-potential-custom-element-name: 1.0.1 + lru-cache: 11.2.4 + + '@asamuzakjp/nwsapi@2.3.9': {} + '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.27.1 @@ -4809,6 +5678,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/generator@7.28.3': dependencies: '@babel/parser': 7.28.4 @@ -4817,6 +5706,14 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.27.3': dependencies: '@babel/types': 7.28.4 @@ -4867,6 +5764,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/helper-optimise-call-expression@7.27.1': dependencies: '@babel/types': 7.28.4 @@ -4893,6 +5799,8 @@ snapshots: '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-option@7.27.1': {} '@babel/helpers@7.28.4': @@ -4904,6 +5812,10 @@ snapshots: dependencies: '@babel/types': 7.28.4 + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -4922,6 +5834,16 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.4)': dependencies: '@babel/core': 7.28.4 @@ -4964,11 +5886,30 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@babel/types@7.28.4': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@bcoe/v8-coverage@1.0.2': {} + '@better-auth/core@1.3.26': dependencies: better-call: 1.0.19 @@ -4986,6 +5927,30 @@ snapshots: dependencies: statuses: 2.0.2 + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-syntax-patches-for-csstree@1.0.14(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/css-tokenizer@3.0.4': {} + '@cypress/request@3.0.9': dependencies: aws-sign2: 0.7.0 @@ -5063,147 +6028,225 @@ snapshots: '@esbuild/aix-ppc64@0.25.10': optional: true + '@esbuild/aix-ppc64@0.27.1': + optional: true + '@esbuild/android-arm64@0.18.20': optional: true '@esbuild/android-arm64@0.25.10': optional: true + '@esbuild/android-arm64@0.27.1': + optional: true + '@esbuild/android-arm@0.18.20': optional: true '@esbuild/android-arm@0.25.10': optional: true + '@esbuild/android-arm@0.27.1': + optional: true + '@esbuild/android-x64@0.18.20': optional: true '@esbuild/android-x64@0.25.10': optional: true + '@esbuild/android-x64@0.27.1': + optional: true + '@esbuild/darwin-arm64@0.18.20': optional: true '@esbuild/darwin-arm64@0.25.10': optional: true + '@esbuild/darwin-arm64@0.27.1': + optional: true + '@esbuild/darwin-x64@0.18.20': optional: true '@esbuild/darwin-x64@0.25.10': optional: true + '@esbuild/darwin-x64@0.27.1': + optional: true + '@esbuild/freebsd-arm64@0.18.20': optional: true '@esbuild/freebsd-arm64@0.25.10': optional: true + '@esbuild/freebsd-arm64@0.27.1': + optional: true + '@esbuild/freebsd-x64@0.18.20': optional: true '@esbuild/freebsd-x64@0.25.10': optional: true + '@esbuild/freebsd-x64@0.27.1': + optional: true + '@esbuild/linux-arm64@0.18.20': optional: true '@esbuild/linux-arm64@0.25.10': optional: true + '@esbuild/linux-arm64@0.27.1': + optional: true + '@esbuild/linux-arm@0.18.20': optional: true '@esbuild/linux-arm@0.25.10': optional: true + '@esbuild/linux-arm@0.27.1': + optional: true + '@esbuild/linux-ia32@0.18.20': optional: true '@esbuild/linux-ia32@0.25.10': optional: true + '@esbuild/linux-ia32@0.27.1': + optional: true + '@esbuild/linux-loong64@0.18.20': optional: true '@esbuild/linux-loong64@0.25.10': optional: true + '@esbuild/linux-loong64@0.27.1': + optional: true + '@esbuild/linux-mips64el@0.18.20': optional: true '@esbuild/linux-mips64el@0.25.10': optional: true + '@esbuild/linux-mips64el@0.27.1': + optional: true + '@esbuild/linux-ppc64@0.18.20': optional: true '@esbuild/linux-ppc64@0.25.10': optional: true + '@esbuild/linux-ppc64@0.27.1': + optional: true + '@esbuild/linux-riscv64@0.18.20': optional: true '@esbuild/linux-riscv64@0.25.10': optional: true + '@esbuild/linux-riscv64@0.27.1': + optional: true + '@esbuild/linux-s390x@0.18.20': optional: true '@esbuild/linux-s390x@0.25.10': optional: true + '@esbuild/linux-s390x@0.27.1': + optional: true + '@esbuild/linux-x64@0.18.20': optional: true '@esbuild/linux-x64@0.25.10': optional: true + '@esbuild/linux-x64@0.27.1': + optional: true + '@esbuild/netbsd-arm64@0.25.10': optional: true + '@esbuild/netbsd-arm64@0.27.1': + optional: true + '@esbuild/netbsd-x64@0.18.20': optional: true '@esbuild/netbsd-x64@0.25.10': optional: true + '@esbuild/netbsd-x64@0.27.1': + optional: true + '@esbuild/openbsd-arm64@0.25.10': optional: true + '@esbuild/openbsd-arm64@0.27.1': + optional: true + '@esbuild/openbsd-x64@0.18.20': optional: true '@esbuild/openbsd-x64@0.25.10': optional: true + '@esbuild/openbsd-x64@0.27.1': + optional: true + '@esbuild/openharmony-arm64@0.25.10': optional: true + '@esbuild/openharmony-arm64@0.27.1': + optional: true + '@esbuild/sunos-x64@0.18.20': optional: true '@esbuild/sunos-x64@0.25.10': optional: true + '@esbuild/sunos-x64@0.27.1': + optional: true + '@esbuild/win32-arm64@0.18.20': optional: true '@esbuild/win32-arm64@0.25.10': optional: true + '@esbuild/win32-arm64@0.27.1': + optional: true + '@esbuild/win32-ia32@0.18.20': optional: true '@esbuild/win32-ia32@0.25.10': optional: true + '@esbuild/win32-ia32@0.27.1': + optional: true + '@esbuild/win32-x64@0.18.20': optional: true '@esbuild/win32-x64@0.25.10': optional: true + '@esbuild/win32-x64@0.27.1': + optional: true + '@eslint-community/eslint-utils@4.9.0(eslint@9.36.0(jiti@2.6.1))': dependencies: eslint: 9.36.0(jiti@2.6.1) @@ -6017,6 +7060,74 @@ snapshots: react-dom: 19.1.0(react@19.1.0) react-promise-suspense: 0.3.4 + '@rolldown/pluginutils@1.0.0-beta.53': {} + + '@rollup/rollup-android-arm-eabi@4.53.5': + optional: true + + '@rollup/rollup-android-arm64@4.53.5': + optional: true + + '@rollup/rollup-darwin-arm64@4.53.5': + optional: true + + '@rollup/rollup-darwin-x64@4.53.5': + optional: true + + '@rollup/rollup-freebsd-arm64@4.53.5': + optional: true + + '@rollup/rollup-freebsd-x64@4.53.5': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.53.5': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.53.5': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.53.5': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.53.5': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.53.5': + optional: true + + '@rollup/rollup-linux-x64-musl@4.53.5': + optional: true + + '@rollup/rollup-openharmony-arm64@4.53.5': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.53.5': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.53.5': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.53.5': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.5': + optional: true + '@rtsao/scc@1.1.0': {} '@rushstack/eslint-patch@1.12.0': {} @@ -6043,6 +7154,8 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} + '@standard-schema/spec@1.1.0': {} + '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -6134,6 +7247,40 @@ snapshots: '@tanstack/table-core@8.21.3': {} + '@testing-library/dom@10.4.1': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/runtime': 7.28.4 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.9.1': + dependencies: + '@adobe/css-tools': 4.4.4 + aria-query: 5.3.2 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + picocolors: 1.1.1 + redent: 3.0.0 + + '@testing-library/react@16.3.1(@testing-library/dom@10.4.1)(@types/react-dom@19.2.0(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@babel/runtime': 7.28.4 + '@testing-library/dom': 10.4.1 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.2.0 + '@types/react-dom': 19.2.0(@types/react@19.2.0) + + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': + dependencies: + '@testing-library/dom': 10.4.1 + '@trpc/client@11.7.0(@trpc/server@11.7.0(typescript@5.9.3))(typescript@5.9.3)': dependencies: '@trpc/server': 11.7.0(typescript@5.9.3) @@ -6172,6 +7319,34 @@ snapshots: tslib: 2.8.1 optional: true + '@types/aria-query@5.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.28.4 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.28.4 + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + '@types/cookie@0.6.0': {} '@types/cypress-dotenv@3.0.0(dotenv@17.2.3)': @@ -6203,6 +7378,8 @@ snapshots: '@types/d3-timer@3.0.2': {} + '@types/deep-eql@4.0.2': {} + '@types/estree@1.0.8': {} '@types/json-schema@7.0.15': {} @@ -6237,6 +7414,10 @@ snapshots: '@types/statuses@2.0.6': {} + '@types/testing-library__jest-dom@6.0.0': + dependencies: + '@testing-library/jest-dom': 6.9.1 + '@types/tmp@0.2.6': {} '@types/yauzl@2.10.3': @@ -6396,6 +7577,75 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true + '@vitejs/plugin-react@5.1.2(vite@7.3.0(@types/node@20.19.19)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6))': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) + '@rolldown/pluginutils': 1.0.0-beta.53 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.3.0(@types/node@20.19.19)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6) + transitivePeerDependencies: + - supports-color + + '@vitest/coverage-v8@4.0.16(vitest@4.0.16(@types/node@20.19.19)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.1)(msw@2.11.3(@types/node@20.19.19)(typescript@5.9.3))(tsx@4.20.6))': + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.0.16 + ast-v8-to-istanbul: 0.3.9 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.2.0 + magicast: 0.5.1 + obug: 2.1.1 + std-env: 3.10.0 + tinyrainbow: 3.0.3 + vitest: 4.0.16(@types/node@20.19.19)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.1)(msw@2.11.3(@types/node@20.19.19)(typescript@5.9.3))(tsx@4.20.6) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@4.0.16': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.16 + '@vitest/utils': 4.0.16 + chai: 6.2.1 + tinyrainbow: 3.0.3 + + '@vitest/mocker@4.0.16(msw@2.11.3(@types/node@20.19.19)(typescript@5.9.3))(vite@7.3.0(@types/node@20.19.19)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6))': + dependencies: + '@vitest/spy': 4.0.16 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + msw: 2.11.3(@types/node@20.19.19)(typescript@5.9.3) + vite: 7.3.0(@types/node@20.19.19)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6) + + '@vitest/pretty-format@4.0.16': + dependencies: + tinyrainbow: 3.0.3 + + '@vitest/runner@4.0.16': + dependencies: + '@vitest/utils': 4.0.16 + pathe: 2.0.3 + + '@vitest/snapshot@4.0.16': + dependencies: + '@vitest/pretty-format': 4.0.16 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.0.16': {} + + '@vitest/utils@4.0.16': + dependencies: + '@vitest/pretty-format': 4.0.16 + tinyrainbow: 3.0.3 + accepts@2.0.0: dependencies: mime-types: 3.0.1 @@ -6435,6 +7685,8 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + ansis@4.2.0: {} arch@2.2.0: {} @@ -6445,6 +7697,10 @@ snapshots: dependencies: tslib: 2.8.1 + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + aria-query@5.3.2: {} array-buffer-byte-length@1.0.2: @@ -6526,12 +7782,20 @@ snapshots: assert-plus@1.0.0: {} + assertion-error@2.0.1: {} + ast-types-flow@0.0.8: {} ast-types@0.16.1: dependencies: tslib: 2.8.1 + ast-v8-to-istanbul@0.3.9: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 9.0.1 + astral-regex@2.0.0: {} async-function@1.0.0: {} @@ -6598,6 +7862,10 @@ snapshots: set-cookie-parser: 2.7.1 uncrypto: 0.1.3 + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + blob-util@2.0.2: {} bluebird@3.7.2: {} @@ -6675,6 +7943,8 @@ snapshots: caseless@0.12.0: {} + chai@6.2.1: {} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -6786,6 +8056,21 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css-tree@3.1.0: + dependencies: + mdn-data: 2.12.2 + source-map-js: 1.2.1 + + css.escape@1.5.1: {} + + cssstyle@5.3.4(postcss@8.5.6): + dependencies: + '@asamuzakjp/css-color': 4.1.1 + '@csstools/css-syntax-patches-for-csstree': 1.0.14(postcss@8.5.6) + css-tree: 3.1.0 + transitivePeerDependencies: + - postcss + csstype@3.1.3: {} cypress-dotenv@3.0.1(cypress@15.5.0)(dotenv@17.2.3): @@ -6898,6 +8183,11 @@ snapshots: data-uri-to-buffer@4.0.1: {} + data-urls@6.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 15.1.0 + data-view-buffer@1.0.2: dependencies: call-bound: 1.0.4 @@ -6936,6 +8226,8 @@ snapshots: decimal.js-light@2.5.1: {} + decimal.js@10.6.0: {} + dedent@1.7.0: {} deep-is@0.1.4: {} @@ -6960,6 +8252,8 @@ snapshots: depd@2.0.0: {} + dequal@2.0.3: {} + detect-libc@2.1.1: {} detect-node-es@1.1.0: {} @@ -6970,6 +8264,10 @@ snapshots: dependencies: esutils: 2.0.3 + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + dom-helpers@5.2.1: dependencies: '@babel/runtime': 7.28.4 @@ -7063,6 +8361,8 @@ snapshots: entities@4.5.0: {} + entities@6.0.1: {} + env-paths@2.2.1: {} error-ex@1.3.4: @@ -7149,6 +8449,8 @@ snapshots: iterator.prototype: 1.1.5 safe-array-concat: 1.1.3 + es-module-lexer@1.7.0: {} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -7231,6 +8533,35 @@ snapshots: '@esbuild/win32-ia32': 0.25.10 '@esbuild/win32-x64': 0.25.10 + esbuild@0.27.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.1 + '@esbuild/android-arm': 0.27.1 + '@esbuild/android-arm64': 0.27.1 + '@esbuild/android-x64': 0.27.1 + '@esbuild/darwin-arm64': 0.27.1 + '@esbuild/darwin-x64': 0.27.1 + '@esbuild/freebsd-arm64': 0.27.1 + '@esbuild/freebsd-x64': 0.27.1 + '@esbuild/linux-arm': 0.27.1 + '@esbuild/linux-arm64': 0.27.1 + '@esbuild/linux-ia32': 0.27.1 + '@esbuild/linux-loong64': 0.27.1 + '@esbuild/linux-mips64el': 0.27.1 + '@esbuild/linux-ppc64': 0.27.1 + '@esbuild/linux-riscv64': 0.27.1 + '@esbuild/linux-s390x': 0.27.1 + '@esbuild/linux-x64': 0.27.1 + '@esbuild/netbsd-arm64': 0.27.1 + '@esbuild/netbsd-x64': 0.27.1 + '@esbuild/openbsd-arm64': 0.27.1 + '@esbuild/openbsd-x64': 0.27.1 + '@esbuild/openharmony-arm64': 0.27.1 + '@esbuild/sunos-x64': 0.27.1 + '@esbuild/win32-arm64': 0.27.1 + '@esbuild/win32-ia32': 0.27.1 + '@esbuild/win32-x64': 0.27.1 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -7436,6 +8767,10 @@ snapshots: estraverse@5.3.0: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + esutils@2.0.3: {} etag@1.8.1: {} @@ -7493,6 +8828,8 @@ snapshots: dependencies: pify: 2.3.0 + expect-type@1.3.0: {} + express-rate-limit@7.5.1(express@5.1.0): dependencies: express: 5.1.0 @@ -7765,6 +9102,8 @@ snapshots: define-properties: 1.2.1 gopd: 1.2.0 + globrex@0.1.2: {} + gopd@1.2.0: {} graceful-fs@4.2.11: {} @@ -7773,6 +9112,8 @@ snapshots: graphql@16.11.0: {} + gsap@3.14.2: {} + has-bigints@1.1.0: {} has-flag@4.0.0: {} @@ -7802,6 +9143,12 @@ snapshots: headers-polyfill@4.0.3: {} + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + + html-escaper@2.0.2: {} + html-to-text@9.0.5: dependencies: '@selderee/plugin-htmlparser2': 0.11.0 @@ -7825,6 +9172,13 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + http-signature@1.4.0: dependencies: assert-plus: 1.0.0 @@ -7973,6 +9327,8 @@ snapshots: is-plain-obj@4.1.0: {} + is-potential-custom-element-name@1.0.1: {} + is-promise@4.0.0: {} is-regex@1.2.1: @@ -8042,6 +9398,27 @@ snapshots: isstream@0.1.2: {} + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + debug: 4.4.3(supports-color@8.1.1) + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + iterator.prototype@1.1.5: dependencies: define-data-property: 1.1.4 @@ -8057,12 +9434,42 @@ snapshots: js-tokens@4.0.0: {} + js-tokens@9.0.1: {} + js-yaml@4.1.0: dependencies: argparse: 2.0.1 jsbn@0.1.1: {} + jsdom@27.3.0(postcss@8.5.6): + dependencies: + '@acemir/cssom': 0.9.29 + '@asamuzakjp/dom-selector': 6.7.6 + cssstyle: 5.3.4(postcss@8.5.6) + data-urls: 6.0.0 + decimal.js: 10.6.0 + 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 + parse5: 8.0.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 6.0.0 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 8.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 15.1.0 + ws: 8.18.3 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - postcss + - supports-color + - utf-8-validate + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -8219,6 +9626,8 @@ snapshots: dependencies: js-tokens: 4.0.0 + lru-cache@11.2.4: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -8227,12 +9636,30 @@ snapshots: dependencies: react: 19.1.0 + lz-string@1.5.0: {} + magic-string@0.30.19: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.5.1: + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.2 + math-intrinsics@1.1.0: {} + mdn-data@2.12.2: {} + media-typer@1.1.0: {} merge-descriptors@2.0.0: {} @@ -8262,6 +9689,8 @@ snapshots: mimic-function@5.0.1: {} + min-indent@1.0.1: {} + minimatch@10.0.3: dependencies: '@isaacs/brace-expansion': 5.0.0 @@ -8336,6 +9765,11 @@ snapshots: negotiator@1.0.0: {} + next-router-mock@1.0.4(next@15.5.4(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0): + dependencies: + next: 15.5.4(@babel/core@7.28.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: react: 19.1.0 @@ -8437,6 +9871,8 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + obug@2.1.1: {} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -8511,6 +9947,10 @@ snapshots: parse-ms@4.0.0: {} + parse5@8.0.0: + dependencies: + entities: 6.0.1 + parseley@0.12.1: dependencies: leac: 0.6.0 @@ -8532,6 +9972,8 @@ snapshots: path-to-regexp@8.3.0: {} + pathe@2.0.3: {} + peberminta@0.9.0: {} pend@1.2.0: {} @@ -8590,6 +10032,12 @@ snapshots: pretty-bytes@5.6.0: {} + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + pretty-ms@9.3.0: dependencies: parse-ms: 4.0.0 @@ -8662,12 +10110,16 @@ snapshots: react-is@16.13.1: {} + react-is@17.0.2: {} + react-is@18.3.1: {} react-promise-suspense@0.3.4: dependencies: fast-deep-equal: 2.0.1 + react-refresh@0.18.0: {} + react-remove-scroll-bar@2.3.8(@types/react@19.2.0)(react@19.1.0): dependencies: react: 19.1.0 @@ -8739,6 +10191,11 @@ snapshots: tiny-invariant: 1.3.3 victory-vendor: 36.9.2 + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + reflect-metadata@0.2.2: {} reflect.getprototypeof@1.0.10: @@ -8767,6 +10224,8 @@ snapshots: require-directory@2.1.1: {} + require-from-string@2.0.2: {} + resend@6.1.2(@react-email/render@1.3.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)): optionalDependencies: '@react-email/render': 1.3.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -8803,6 +10262,34 @@ snapshots: rfdc@1.4.1: {} + rollup@4.53.5: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.53.5 + '@rollup/rollup-android-arm64': 4.53.5 + '@rollup/rollup-darwin-arm64': 4.53.5 + '@rollup/rollup-darwin-x64': 4.53.5 + '@rollup/rollup-freebsd-arm64': 4.53.5 + '@rollup/rollup-freebsd-x64': 4.53.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.5 + '@rollup/rollup-linux-arm-musleabihf': 4.53.5 + '@rollup/rollup-linux-arm64-gnu': 4.53.5 + '@rollup/rollup-linux-arm64-musl': 4.53.5 + '@rollup/rollup-linux-loong64-gnu': 4.53.5 + '@rollup/rollup-linux-ppc64-gnu': 4.53.5 + '@rollup/rollup-linux-riscv64-gnu': 4.53.5 + '@rollup/rollup-linux-riscv64-musl': 4.53.5 + '@rollup/rollup-linux-s390x-gnu': 4.53.5 + '@rollup/rollup-linux-x64-gnu': 4.53.5 + '@rollup/rollup-linux-x64-musl': 4.53.5 + '@rollup/rollup-openharmony-arm64': 4.53.5 + '@rollup/rollup-win32-arm64-msvc': 4.53.5 + '@rollup/rollup-win32-ia32-msvc': 4.53.5 + '@rollup/rollup-win32-x64-gnu': 4.53.5 + '@rollup/rollup-win32-x64-msvc': 4.53.5 + fsevents: 2.3.3 + rou3@0.5.1: {} router@2.2.0: @@ -8846,6 +10333,10 @@ snapshots: safer-buffer@2.1.2: {} + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + scheduler@0.26.0: {} selderee@0.11.0: @@ -9009,6 +10500,8 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -9055,10 +10548,14 @@ snapshots: stable-hash@0.0.5: {} + stackback@0.0.2: {} + statuses@2.0.1: {} statuses@2.0.2: {} + std-env@3.10.0: {} + stdin-discarder@0.2.2: {} stop-iteration-iterator@1.1.0: @@ -9150,6 +10647,10 @@ snapshots: strip-final-newline@4.0.0: {} + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + strip-json-comments@3.1.1: {} styled-jsx@5.1.6(@babel/core@7.28.4)(react@19.1.0): @@ -9169,6 +10670,8 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + symbol-tree@3.2.4: {} + systeminformation@5.27.7: {} tailwind-merge@3.3.1: {} @@ -9191,13 +10694,19 @@ snapshots: tiny-invariant@1.3.3: {} + tinybench@2.9.0: {} + tinyexec@1.0.1: {} + tinyexec@1.0.2: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyrainbow@3.0.3: {} + tldts-core@6.1.86: {} tldts-core@7.0.16: {} @@ -9226,6 +10735,10 @@ snapshots: dependencies: tldts: 7.0.16 + tr46@6.0.0: + dependencies: + punycode: 2.3.1 + tree-kill@1.2.2: {} ts-api-utils@2.1.0(typescript@5.9.3): @@ -9237,6 +10750,10 @@ snapshots: '@ts-morph/common': 0.27.0 code-block-writer: 13.0.3 + tsconfck@3.1.6(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 @@ -9421,8 +10938,89 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 + vite-tsconfig-paths@6.0.1(typescript@5.9.3)(vite@7.3.0(@types/node@20.19.19)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6)): + dependencies: + debug: 4.4.3(supports-color@8.1.1) + globrex: 0.1.2 + tsconfck: 3.1.6(typescript@5.9.3) + optionalDependencies: + vite: 7.3.0(@types/node@20.19.19)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6) + transitivePeerDependencies: + - supports-color + - typescript + + vite@7.3.0(@types/node@20.19.19)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6): + dependencies: + esbuild: 0.27.1 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.5 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 20.19.19 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.1 + tsx: 4.20.6 + + vitest@4.0.16(@types/node@20.19.19)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.1)(msw@2.11.3(@types/node@20.19.19)(typescript@5.9.3))(tsx@4.20.6): + dependencies: + '@vitest/expect': 4.0.16 + '@vitest/mocker': 4.0.16(msw@2.11.3(@types/node@20.19.19)(typescript@5.9.3))(vite@7.3.0(@types/node@20.19.19)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6)) + '@vitest/pretty-format': 4.0.16 + '@vitest/runner': 4.0.16 + '@vitest/snapshot': 4.0.16 + '@vitest/spy': 4.0.16 + '@vitest/utils': 4.0.16 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.3.0(@types/node@20.19.19)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.19.19 + jsdom: 27.3.0(postcss@8.5.6) + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + web-streams-polyfill@3.3.3: {} + webidl-conversions@8.0.0: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + whatwg-url@15.1.0: + dependencies: + tr46: 6.0.0 + webidl-conversions: 8.0.0 + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 @@ -9472,6 +11070,11 @@ snapshots: dependencies: isexe: 3.1.1 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} wrap-ansi@6.2.0: @@ -9488,6 +11091,12 @@ snapshots: wrappy@1.0.2: {} + ws@8.18.3: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + xtend@4.0.2: {} y18n@5.0.8: {} diff --git a/public/monitor-chart.svg b/public/monitor-chart.svg new file mode 100644 index 0000000..bc17296 --- /dev/null +++ b/public/monitor-chart.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/public/test.png b/public/test.png new file mode 100644 index 0000000..2db15b2 Binary files /dev/null and b/public/test.png differ diff --git a/public/transaction-form.png b/public/transaction-form.png new file mode 100644 index 0000000..5b97cab Binary files /dev/null and b/public/transaction-form.png differ diff --git a/public/transactions-table.png b/public/transactions-table.png new file mode 100644 index 0000000..b307a23 Binary files /dev/null and b/public/transactions-table.png differ diff --git a/src/app/(auth)/layout.tsx b/src/app/(auth)/layout.tsx index 8a23935..9b60cb8 100644 --- a/src/app/(auth)/layout.tsx +++ b/src/app/(auth)/layout.tsx @@ -1,11 +1,9 @@ -import Container from '@/components/ui/container'; +import Container from "@/components/ui/container"; const AuthLayout = ({ children }: { children: React.ReactNode }) => { return (
-
- {children} -
+
{children}
); diff --git a/src/app/actions/auth/auth.actions.ts b/src/app/actions/auth/auth.actions.ts index f3a9c23..a5a73eb 100644 --- a/src/app/actions/auth/auth.actions.ts +++ b/src/app/actions/auth/auth.actions.ts @@ -1,20 +1,23 @@ -'use server'; +"use server"; import { emailSchema, passwordSchema, signInSchema, signUpSchema, -} from './auth.schema'; -import { signUp } from '@/lib/auth/auth-client'; -import { auth } from '@/lib/auth/auth'; -import { headers } from 'next/headers'; -import { APIError } from 'better-auth'; -import { ROUTES } from '@/types'; +} from "./auth.schema"; +import { signUp } from "@/lib/auth/auth-client"; +import { auth } from "@/lib/auth/auth"; +import { headers } from "next/headers"; +import { APIError } from "better-auth"; +import { ROUTES } from "@/types"; +import { db } from "@/db"; +import { account } from "@/db/schema"; +import { eq } from "drizzle-orm"; export const signInUser = async (initialData: unknown, formData: FormData) => { const validatedData = signInSchema.safeParse({ - email: formData.get('email'), - password: formData.get('password'), + email: formData.get("email"), + password: formData.get("password"), }); if (!validatedData.success) { return { @@ -23,8 +26,8 @@ export const signInUser = async (initialData: unknown, formData: FormData) => { }; } const { email, password } = validatedData.data; - console.log('Signing in user with email:', email); - console.log('Signing in user with password:', password); + console.log("Signing in user with email:", email); + console.log("Signing in user with password:", password); try { const response = await auth.api.signInEmail({ body: { @@ -45,13 +48,13 @@ export const signInUser = async (initialData: unknown, formData: FormData) => { }; } } catch (error) { - console.error('Error during sign-in:', error); + console.error("Error during sign-in:", error); if (error instanceof APIError) { return { success: false, errors: { - email: [error.body?.message || 'Invalid email or password'], + email: [error.body?.message || "Invalid email or password"], password: [], }, }; @@ -65,10 +68,10 @@ export const signUpCreateUser = async ( formData: FormData ) => { const validatedData = signUpSchema.safeParse({ - name: formData.get('name'), - email: formData.get('email'), - password: formData.get('password'), - confirmPassword: formData.get('confirmPassword'), + name: formData.get("name"), + email: formData.get("email"), + password: formData.get("password"), + confirmPassword: formData.get("confirmPassword"), }); if (!validatedData.success) { return { @@ -83,15 +86,38 @@ export const signUpCreateUser = async ( email, password, - callbackURL: process.env.BASE_URL! + '/dashboard', + callbackURL: process.env.BASE_URL! + "/dashboard", name, }, { - onSuccess: (user) => { - console.log('User signed up successfully:', user); + onSuccess: async (data) => { + try { + const userId = data?.data?.user?.id; + + if (!userId) { + console.error( + "Error updating user email in account table: missing user id in sign-up response" + ); + return; + } + + await db + .update(account) + .set({ + userEmail: email, + }) + .where(eq(account.userId, data.data.user.id)); + } catch (error) { + if (error instanceof Error) { + console.error( + "Error updating user email in account table:", + error.message + ); + } + } }, onError: (error) => { - console.error('Error signing up user:', error); + console.error("Error signing up user:", error); }, } ); @@ -118,14 +144,14 @@ export const signOutUser = async () => { if (response) { return { success: response, - error: 'No error', + error: "No error", }; } } catch (error) { - console.error('Error during sign-out:', error); + console.error("Error during sign-out:", error); return { success: false, - error: 'Error signing out', + error: "Error signing out", }; } }; @@ -135,9 +161,8 @@ export const forgotPassword = async ( formData: FormData ) => { const validatedData = emailSchema.safeParse({ - email: formData.get('email'), + email: formData.get("email"), }); - console.log(validatedData); if (!validatedData.success) { return { success: false, @@ -146,8 +171,20 @@ export const forgotPassword = async ( } const { email } = validatedData.data; - console.log('Resetting password for email:', email); + try { + const isRegisteredWithPassword = + await isAccountRegisteredWithPassword(email); + if (!isRegisteredWithPassword) { + return { + success: false, + errors: { + email: [ + "This email is used by OAuth provider. Please use the OAuth provider to sign in.", + ], + }, + }; + } await auth.api.requestPasswordReset({ body: { email, // required @@ -156,17 +193,17 @@ export const forgotPassword = async ( }); return { success: true, errors: { email: [] } }; } catch (error) { - console.error('Error during password reset:', error); + console.error("Error during password reset:", error); if (error instanceof APIError) { return { success: false, - errors: { email: [error.body?.message || 'Error sending reset email'] }, + errors: { email: [error.body?.message || "Error sending reset email"] }, }; } // Handle non-APIError exceptions return { success: false, - errors: { email: ['An unexpected error occurred. Please try again.'] }, + errors: { email: ["An unexpected error occurred. Please try again."] }, }; } }; @@ -176,8 +213,8 @@ export const resetPassword = async ( formData: FormData ) => { const validatedData = passwordSchema.safeParse({ - newPassword: formData.get('newPassword'), - confirmPassword: formData.get('confirmPassword'), + newPassword: formData.get("newPassword"), + confirmPassword: formData.get("confirmPassword"), }); if (!validatedData.success) { return { @@ -185,7 +222,7 @@ export const resetPassword = async ( errors: validatedData.error.flatten().fieldErrors, }; } - const token = formData.get('token') as string; + const token = formData.get("token") as string; const { newPassword } = validatedData.data; try { const data = await auth.api.resetPassword({ @@ -199,20 +236,76 @@ export const resetPassword = async ( return { success: true, errors: { newPassword: [] } }; } } catch (error) { - console.error('Error during password reset:', error); + console.error("Error during password reset:", error); if (error instanceof APIError) { return { success: false, errors: { - newPassword: [error.body?.message || 'Error resetting password'], + newPassword: [error.body?.message || "Error resetting password"], }, }; } return { success: false, errors: { - newPassword: ['An unexpected error occurred. Please try again.'], + newPassword: ["An unexpected error occurred. Please try again."], }, }; } }; + +const isAccountRegisteredWithPassword = async ( + email: string +): Promise => { + try { + const data = await db + .select() + .from(account) + .where(eq(account.userEmail, email)); + if (data.length === 0) { + return false; + } + const acc = data[0]; + return acc.password !== null && acc.password !== undefined; + } catch (error) { + if (error instanceof Error) { + console.error( + "Error checking account registration method:", + error.message + ); + } + return false; + } +}; + +export const handleMagicLinkSignIn = async () => { + try { + if (!process.env.TEST_EMAIL || !process.env.TEST_PASSWORD) { + console.error("Guest credentials are not set."); + return { + success: false, + message: "Guest login is currently not configured.", + }; + } + const res = await auth.api.signInEmail({ + body: { + email: process.env.TEST_EMAIL!, + password: process.env.TEST_PASSWORD!, + callbackURL: process.env.BASE_URL! + ROUTES.DASHBOARD, + }, + headers: await headers(), + }); + if (res.user) { + return { + success: true, + message: "You have been logged in as a guest user.", + }; + } + } catch (error) { + console.error("Error during guest sign-in:", error); + return { + success: false, + message: "Failed to log in as a guest user. Try again later.", + }; + } +}; diff --git a/src/app/dashboard/(transactions)/layout.tsx b/src/app/dashboard/(transactions)/layout.tsx index e613cb6..b44e114 100644 --- a/src/app/dashboard/(transactions)/layout.tsx +++ b/src/app/dashboard/(transactions)/layout.tsx @@ -1,13 +1,13 @@ -import Container from '@/components/ui/container'; +import Container from "@/components/ui/container"; -import CustomBreadCrumb from '@/components/features/CustomBreadCrumb'; +import CustomBreadCrumb from "@/components/features/CustomBreadCrumb"; const DashboardLayout = ({ children }: { children: React.ReactNode }) => { return ( - + -
{children}
+
{children}
); }; diff --git a/src/app/dashboard/(transactions)/transactions/page.tsx b/src/app/dashboard/(transactions)/transactions/page.tsx index a934489..afdd1bd 100644 --- a/src/app/dashboard/(transactions)/transactions/page.tsx +++ b/src/app/dashboard/(transactions)/transactions/page.tsx @@ -1,13 +1,13 @@ -import { NextPage } from 'next'; -import { TransactionColumns } from '@/components/dashboard/transactions-table/colums'; -import TransactionTable from '@/components/dashboard/transactions-table/TransactionTable'; -import TransactionTableSkeleton from '@/components/dashboard/transactions-table/TransactionTableSkeleton'; -import { auth } from '@/lib/auth/auth'; -import { headers } from 'next/headers'; -import { redirect } from 'next/navigation'; -import { ROUTES } from '@/types'; -import { Suspense } from 'react'; -import { trpcServer } from '@/lib/trpc/server'; +import { NextPage } from "next"; +import { TransactionColumns } from "@/components/dashboard/transactions-table/columns"; +import TransactionTable from "@/components/dashboard/transactions-table/TransactionTable"; +import TransactionTableSkeleton from "@/components/dashboard/transactions-table/TransactionTableSkeleton"; +import { auth } from "@/lib/auth/auth"; +import { headers } from "next/headers"; +import { redirect } from "next/navigation"; +import { ROUTES } from "@/types"; +import { Suspense } from "react"; +import { trpcServer } from "@/lib/trpc/server"; type Props = { searchParams: Promise; diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx new file mode 100644 index 0000000..c7098a9 --- /dev/null +++ b/src/app/dashboard/layout.tsx @@ -0,0 +1,5 @@ +const DashboardLayout = ({ children }: { children: React.ReactNode }) => { + return
{children}
; +}; + +export default DashboardLayout; diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index 1482b3f..330b7b6 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -1,13 +1,13 @@ -import DashboardLandingPageConent from '@/components/dashboard/landing-page/DashboardLandingPage'; -import { auth } from '@/lib/auth/auth'; -import { trpcServer } from '@/lib/trpc/server'; -import { ROUTES } from '@/types'; -import { Metadata, NextPage } from 'next'; -import { headers } from 'next/headers'; -import { redirect } from 'next/navigation'; +import DashboardLandingPageContent from "@/components/dashboard/landing-page/DashboardLandingPage"; +import { auth } from "@/lib/auth/auth"; +import { trpcServer } from "@/lib/trpc/server"; +import { ROUTES } from "@/types"; +import { Metadata, NextPage } from "next"; +import { headers } from "next/headers"; +import { redirect } from "next/navigation"; export const metadata: Metadata = { - title: 'Dashboard', - description: 'User Dashboard Page', + title: "Dashboard", + description: "User Dashboard Page", }; const DashboardPage: NextPage = async () => { @@ -30,15 +30,15 @@ const DashboardPage: NextPage = async () => { trpcServer.dashboard.summary({ from }), trpcServer.dashboard.monthlyFlow({ months: 12 }), trpcServer.dashboard.getTransactionByCategory({ - transactionType: 'income', + transactionType: "income", }), trpcServer.dashboard.getTransactionByCategory({ - transactionType: 'expense', + transactionType: "expense", }), ]); return ( <> - + - {children} +
+ + {children} +
diff --git a/src/app/page.tsx b/src/app/page.tsx index 3e0d06c..59f7f0f 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,7 +1,55 @@ -export default async function Home() { +import Carousel from "@/components/features/Carousel"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import Container from "@/components/ui/container"; +import Typography from "@/components/ui/typogprahy"; +import Link from "next/dist/client/link"; +import Image from "next/image"; +export default function Home() { return ( -
-

Hello world!

-
+ <> + + + Welcome to Penny Tracker
+
+
+ + + + + Get started by exploring our dashboard + + + + + +
+ + Use the dashboard to monitor your financial activities, write + down your expenses and incomes,and gain insights into your + spending habits. + +
+ +
+
+ Monitor Chart +
+
+
+
+ +
+ +
+
+ ); } diff --git a/src/components/auth/AuthForm.tsx b/src/components/auth/AuthForm.tsx index 195dad4..da18d0d 100644 --- a/src/components/auth/AuthForm.tsx +++ b/src/components/auth/AuthForm.tsx @@ -1,4 +1,4 @@ -'use client'; +"use client"; import { Field, FieldDescription, @@ -6,22 +6,24 @@ import { FieldGroup, FieldLabel, FieldSet, -} from '@/components/ui/field'; -import { Input } from '@/components/ui/input'; -import { useActionState, useCallback, useEffect, useState } from 'react'; -import { Button } from '../ui/button'; -import { Spinner } from '../ui/spinner'; -import { IoLogoGithub } from 'react-icons/io'; -import { FcGoogle } from 'react-icons/fc'; +} from "@/components/ui/field"; +import { Input } from "@/components/ui/input"; +import { useActionState, useCallback, useEffect, useState } from "react"; +import { Button } from "../ui/button"; +import { Spinner } from "../ui/spinner"; +import { IoLogoGithub } from "react-icons/io"; +import { FcGoogle } from "react-icons/fc"; -import { toast } from 'sonner'; -import { signIn } from '@/lib/auth/auth-client'; -import { Card, CardContent, CardTitle } from '../ui/card'; -import Image from 'next/image'; -import Link from 'next/link'; -import { ROUTES } from '@/types'; -import { useRouter } from 'next/navigation'; -import { EyeIcon, EyeOffIcon } from 'lucide-react'; +import { toast } from "sonner"; +import { signIn } from "@/lib/auth/auth-client"; +import { Card, CardContent } from "../ui/card"; +import Image from "next/image"; +import Link from "next/link"; +import { ROUTES } from "@/types"; +import { useRouter } from "next/navigation"; +import { EyeIcon, EyeOffIcon } from "lucide-react"; +import Typography from "../ui/typogprahy"; +import { handleMagicLinkSignIn } from "@/app/actions/auth/auth.actions"; type Props = { title: string; @@ -29,7 +31,7 @@ type Props = { authMethod: (initialData: any, formData: FormData) => Promise; // eslint-disable-next-line @typescript-eslint/no-explicit-any initialState: any; - authType: 'sign-in' | 'sign-up'; + authType: "sign-in" | "sign-up"; }; export const AuthForm: React.FC = ({ title, @@ -40,32 +42,56 @@ export const AuthForm: React.FC = ({ const [state, formAction, pending] = useActionState(authMethod, initialState); const [passwordVisible, setPasswordVisible] = useState(false); const [confirmPasswordVisible, setConfirmPasswordVisible] = useState(false); - + const [loadingGuest, setLoadingGuest] = useState(false); const router = useRouter(); const handleRouter = useCallback(() => { if (state?.success) { - if (authType === 'sign-in') { - toast.success('You have successfully logged in', {}); + if (authType === "sign-in") { + toast.success("You have successfully logged in", {}); router.replace(ROUTES.DASHBOARD); router.refresh(); } else { toast.success( - 'Your account has been Created. Please check your email to verify it.', + "Your account has been Created. Please check your email to verify it.", {} ); } } }, [state?.success, authType, router]); + const handleGuestLogin = async () => { + try { + setLoadingGuest(true); + const res = await handleMagicLinkSignIn(); + if (res?.success) { + toast.success(res.message || "Logged in as guest user"); + router.replace(ROUTES.DASHBOARD); + router.refresh(); + } + if (!res?.success) { + toast.error( + res?.message || "Failed to log in as guest user. Try again." + ); + } + } catch (error) { + setLoadingGuest(false); + console.error("Error during guest login:", error); + const errorMessage = + error instanceof Error ? error.message : String(error); + toast.error(`Error during guest login: ${errorMessage}`); + } finally { + setLoadingGuest(false); + } + }; useEffect(() => { handleRouter(); }, [handleRouter]); const handleSignUpWithGithub = async () => { try { signIn.social({ - provider: 'github', + provider: "github", callbackURL: ROUTES.DASHBOARD, - loginHint: 'github', + loginHint: "github", }); } catch (error) { console.log(error); @@ -74,7 +100,7 @@ export const AuthForm: React.FC = ({ const handleSignUpWithGoogle = async () => { try { signIn.social({ - provider: 'google', + provider: "google", callbackURL: ROUTES.DASHBOARD, }); } catch (error) { @@ -83,90 +109,95 @@ export const AuthForm: React.FC = ({ }; return ( - - + + {title} - - + + Sign Up -
-
+
+
- {authType === 'sign-up' && ( + {authType === "sign-up" && ( - Name + Name {!state.errors?.name && ( Choose a name for your account. )} - - {state.errors?.name && state.errors.name.join(', ')} + + {state.errors?.name && state.errors.name.join(", ")} )} - Email + Email {!state.errors?.email && ( Choose an email for your account. )} - - {state.errors?.email && state.errors.email.join(', ')} + + {state.errors?.email && state.errors.email.join(", ")} - - Password + + Password -
+
{passwordVisible ? ( ) : ( ) : (
{state.errors?.confirmPassword && - state.errors.confirmPassword.join(', ')} + state.errors.confirmPassword.join(", ")} )}
- {authType === 'sign-in' && ( -

+ {authType === "sign-in" && ( +

Forgot your password?

)} -
-
-
-

OR

-
+
+ +
+
+
+
+

OR

+
-
-

- {' '} - {authType === 'sign-up' ? 'Sign up with' : 'Sign in with'}{' '} +

+

+ {" "} + {authType === "sign-up" ? "Sign up with" : "Sign in with"}{" "}

diff --git a/src/components/auth/test/AuthForm.test.tsx b/src/components/auth/test/AuthForm.test.tsx new file mode 100644 index 0000000..2d870ee --- /dev/null +++ b/src/components/auth/test/AuthForm.test.tsx @@ -0,0 +1,75 @@ +import { render, screen } from "@testing-library/react"; +import { AuthForm } from "../AuthForm"; +import { expect, vi } from "vitest"; +import userEvent from "@testing-library/user-event"; +vi.mock("next/navigation", async (importOriginal) => { + const actual = await importOriginal(); + const { useRouter } = + await vi.importActual( + "next-router-mock" + ); + const usePathname = vi.fn().mockImplementation(() => { + const router = useRouter(); + return router.pathname; + }); + const useSearchParams = vi.fn().mockImplementation(() => { + const router = useRouter(); + return new URLSearchParams(router.query?.toString()); + }); + return { + ...actual, + useRouter: vi.fn().mockImplementation(useRouter), + usePathname, + useSearchParams, + }; +}); +const mockAuthMethod = vi.fn(); +describe("Transaction Form Test Suites", () => { + beforeEach(() => { + mockAuthMethod.mockClear(); + mockAuthMethod.mockResolvedValue({ success: false, errors: {} }); + }); + it("should render transaction form correctly", () => { + render( + + ); + const transactionFromTitle = screen.getByRole("heading", { level: 2 }); + expect(transactionFromTitle).toBeInTheDocument(); + }); + it("should call authMethod on form submission", async () => { + render( + + ); + const user = userEvent.setup(); + const emailInput = screen.getByRole("textbox", { name: /email/i }); + const nameInput = screen.getByRole("textbox", { name: /name/i }); + const passportInput = screen.getByTestId("password-input"); + const confirmPasswordInput = screen.getByLabelText(/confirm password/i); + const submitButton = screen.getByRole("button", { name: /submit/i }); + expect(emailInput).toBeInTheDocument(); + expect(nameInput).toBeInTheDocument(); + expect(passportInput).toBeInTheDocument(); + expect(confirmPasswordInput).toBeInTheDocument(); + expect(submitButton).toBeInTheDocument(); + await user.type(emailInput, "tess1t@example.com"); + await user.type(nameInput, "Test User"); + await user.type(passportInput, "password123"); + await user.type(confirmPasswordInput, "password123"); + expect(emailInput).toHaveValue("tess1t@example.com"); + expect(nameInput).toHaveValue("Test User"); + expect(passportInput).toHaveValue("password123"); + expect(confirmPasswordInput).toHaveValue("password123"); + await user.click(submitButton); + expect(mockAuthMethod).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/components/dashboard/landing-page/DashboardLandingPage.tsx b/src/components/dashboard/landing-page/DashboardLandingPage.tsx index 5055697..a8cf0e8 100644 --- a/src/components/dashboard/landing-page/DashboardLandingPage.tsx +++ b/src/components/dashboard/landing-page/DashboardLandingPage.tsx @@ -1,20 +1,20 @@ -'use client'; -import { Button } from '@/components/ui/button'; +"use client"; +import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, -} from '@/components/ui/card'; -import Container from '@/components/ui/container'; -import { useSession } from '@/lib/auth/auth-client'; -import { ROUTES } from '@/types'; -import Link from 'next/link'; -import ExpenseIncomePieChart from './ExpenseIncomePieChart'; -import ExpenseIncomeBarChart from './ExpenseIncomeBarChart'; -import CategoryBarChart from './CategoryBarChart'; -import { TbTransactionPound, TbTableDashed } from 'react-icons/tb'; +} from "@/components/ui/card"; +import Container from "@/components/ui/container"; +import { useSession } from "@/lib/auth/auth-client"; +import { ROUTES } from "@/types"; +import Link from "next/link"; +import ExpenseIncomePieChart from "./ExpenseIncomePieChart"; +import ExpenseIncomeBarChart from "./ExpenseIncomeBarChart"; +import CategoryBarChart from "./CategoryBarChart"; +import { TbTransactionPound, TbTableDashed } from "react-icons/tb"; type Props = { summary: { @@ -38,7 +38,7 @@ type Props = { fromDate: Date; toDate: Date; }; -const DashboardLandingPageConent: React.FC = ({ +const DashboardLandingPageContent: React.FC = ({ summary, monthlyFlow, transactionByCategoryIncome, @@ -48,45 +48,45 @@ const DashboardLandingPageConent: React.FC = ({ }) => { const session = useSession(); return ( - -
- - + +
+ + Welcome back, {session?.data?.user.name} - + Here is an overview of your transactions. -
-
+
+
-
+
= ({ transactionByCategoryIncome={transactionByCategoryIncome} transactionByCategoryExpense={transactionByCategoryExpense} /> -
+
); }; -export default DashboardLandingPageConent; +export default DashboardLandingPageContent; diff --git a/src/components/dashboard/transaction-form/TransactionForm.tsx b/src/components/dashboard/transaction-form/TransactionForm.tsx index befecc1..2a8514e 100644 --- a/src/components/dashboard/transaction-form/TransactionForm.tsx +++ b/src/components/dashboard/transaction-form/TransactionForm.tsx @@ -1,5 +1,5 @@ -'use client'; -import { Button } from '@/components/ui/button'; +"use client"; +import { Button } from "@/components/ui/button"; import { Select, SelectContent, @@ -7,7 +7,7 @@ import { SelectItem, SelectTrigger, SelectValue, -} from '@/components/ui/select'; +} from "@/components/ui/select"; import { Field, @@ -16,16 +16,16 @@ import { FieldGroup, FieldLabel, FieldSet, -} from '@/components/ui/field'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'; -import DatePicker from '../../features/DatePicker'; -import { Textarea } from '../../ui/textarea'; -import { Spinner } from '../../ui/spinner'; -import { CATEGORIES } from '@/constants'; -import { SelectTransaction } from '@/db/schema'; -import { useTransactionMutation } from '@/hooks'; +} from "@/components/ui/field"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; +import DatePicker from "../../features/DatePicker"; +import { Textarea } from "../../ui/textarea"; +import { Spinner } from "../../ui/spinner"; +import { CATEGORIES } from "@/constants"; +import { SelectTransaction } from "@/db/schema"; +import { useTransactionMutation } from "@/hooks"; type FieldErrors = { transactionType?: string[]; category?: string[]; @@ -40,7 +40,7 @@ type TransactionFormProps = { const TransactionForm: React.FC = ({ transaction }) => { const isEditMode = !!transaction; const { mutate, isPending, error } = useTransactionMutation( - isEditMode ? 'update' : 'create' + isEditMode ? "update" : "create" ); // Extract Zod field errors const fieldErrors = error?.data?.zodError as FieldErrors | undefined; @@ -53,11 +53,11 @@ const TransactionForm: React.FC = ({ transaction }) => { const formData = new FormData(form); const input = { ...(isEditMode && { id: transaction!.id }), - transactionType: formData.get('transactionType') as 'income' | 'expense', - category: formData.get('category') as string, - amount: Number(formData.get('amount')), - description: formData.get('description') as string, - transactionDate: new Date(formData.get('date') as string), + transactionType: formData.get("transactionType") as "income" | "expense", + category: formData.get("category") as string, + amount: Number(formData.get("amount")), + description: formData.get("description") as string, + transactionDate: new Date(formData.get("date") as string), }; mutate(input, { @@ -69,53 +69,63 @@ const TransactionForm: React.FC = ({ transaction }) => { return (
-
+
-
+
- Transaction Type + Transaction Type -
- - +
+ +
-
- - +
+ +
Choose your transaction - {getFieldError('transactionType') && ( - - {getFieldError('transactionType')} + {getFieldError("transactionType") && ( + + {getFieldError("transactionType")} )} - Category + Category - {getFieldError('category') && ( - - {getFieldError('category')} + {getFieldError("category") && ( + + {getFieldError("category")} )}
-
+
- Transaction Date + Transaction Date - {getFieldError('date') && ( - - {getFieldError('date')} + {getFieldError("date") && ( + + {getFieldError("date")} )} - Amount + Amount Enter transaction amount - {getFieldError('amount') && ( - - {getFieldError('amount')} + {getFieldError("amount") && ( + + {getFieldError("amount")} )}
- Description + Description