diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml new file mode 100644 index 0000000..95fb11b --- /dev/null +++ b/.gitea/workflows/ci.yaml @@ -0,0 +1,177 @@ +name: CI Pipeline +run-name: ${{ gitea.actor }} triggered CI pipeline + +on: + push: + branches: [main, develop, "adilallo/enhancement/TestingFramework"] + pull_request: + branches: [main, develop] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: { node-version: [18, 20] } + env: + NODE_OPTIONS: "--max_old_space_size=4096" + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: npm + - run: npm ci + - run: npm test + + # If the Codecov Action fails on Gitea, replace this with the bash uploader below + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./coverage/lcov.info + flags: unittests + + # Bash uploader alternative (uncomment if the action above has issues) + # - name: Upload coverage to Codecov (bash) + # run: | + # curl -s https://codecov.io/bash > codecov.sh + # bash codecov.sh -t "${{ secrets.CODECOV_TOKEN }}" -f coverage/lcov.info -F unittests + + e2e: + runs-on: ubuntu-latest + strategy: + matrix: { browser: [chromium, firefox, webkit] } + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: 20, cache: npm } + - run: npm ci + - run: npx playwright install --with-deps ${{ matrix.browser }} + - run: npm run build + + # start app, wait, run tests + - run: npm run preview & + env: { CI: true } + - run: npx wait-on http://localhost:3000 + - run: npx playwright test --project=${{ matrix.browser }} + env: { CI: true } + + # package artifacts (keeps file count small) + - name: Package E2E artifacts + if: always() + run: | + tar -czf playwright-${{ matrix.browser }}.tgz playwright-report test-results || true + + - name: Upload E2E artifacts + if: always() + uses: actions/upload-artifact@v3 + with: + name: playwright-results-${{ matrix.browser }} + path: playwright-${{ matrix.browser }}.tgz + retention-days: 30 + + visual-regression: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: 20, cache: npm } + - run: npm ci + - run: npx playwright install --with-deps + - run: npm run build + - run: npm run preview & + env: { CI: true } + - run: npx wait-on http://localhost:3000 + + # Seed snapshots on main branch only (one-time setup) + - name: Seed snapshots (main only) + if: github.ref == 'refs/heads/main' + run: PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --project=chromium + env: { CI: true } + + # Run visual regression tests + - name: Run visual regression tests + run: npx playwright test tests/e2e/visual-regression.spec.ts + env: { CI: true } + + - name: Package visual artifacts + if: always() + run: | + tar -czf visual-regression.tgz test-results tests/e2e/visual-regression.spec.ts-snapshots || true + + - name: Upload visual artifacts + if: always() + uses: actions/upload-artifact@v3 + with: + name: visual-regression-results + path: visual-regression.tgz + retention-days: 30 + + performance: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: 20, cache: npm } + - run: npm ci + + - name: Install LHCI + run: npm i -D @lhci/cli + + # Ensure a Chrome binary is available (works on Linux/macOS runners) + - name: Install Chrome via Puppeteer (portable) + run: | + npx @puppeteer/browsers install chrome@stable -P .cache/puppeteer + echo "CHROME_PATH=$(npx @puppeteer/browsers executable-path chrome@stable -P .cache/puppeteer)" >> $GITHUB_ENV + + - name: Build application + run: npm run build + + - name: Start application + run: npm run preview & + env: { CI: true } + + - name: Wait for application + run: npx wait-on http://localhost:3000 + + - name: Run Lighthouse CI + run: npx lhci autorun --chrome-path="$CHROME_PATH" + env: { CI: true } + + - name: Upload LHCI results + if: always() + uses: actions/upload-artifact@v3 + with: + name: lhci-results + path: lhci-results + + storybook: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: 20, cache: npm } + - run: npm ci + - run: npm run storybook:build:github + - run: npm run test:sb + env: { CI: true } + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: 20, cache: npm } + - run: npm ci + - run: npm run lint + - run: npx prettier --check "**/*.{js,jsx,ts,tsx,json,css,md}" + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: 20, cache: npm } + - run: npm ci + - run: npm run build + - run: npm run storybook:build:github diff --git a/.gitignore b/.gitignore index 9cf2b15..140109c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,23 @@ # testing /coverage +# Playwright +/test-results/ +/playwright-report/ +# Visual regression snapshots (allow these) +!tests/e2e/visual-regression.spec.ts-snapshots/ +!tests/e2e/visual-regression.spec.ts-snapshots/*.png +# Ignore other image files +*.png +*.jpg +*.jpeg +*.gif +*.webm +*.mp4 +*.mov +*.avi +*.mkv + # next.js /.next/ /out/ diff --git a/.lighthouserc.json b/.lighthouserc.json new file mode 100644 index 0000000..0ac0631 --- /dev/null +++ b/.lighthouserc.json @@ -0,0 +1,20 @@ +{ + "ci": { + "collect": { + "url": ["http://localhost:3000/"], + "numberOfRuns": 3 + }, + "assert": { + "assertions": { + "categories:performance": ["warn", { "minScore": 0.9 }], + "categories:accessibility": ["error", { "minScore": 0.9 }], + "first-contentful-paint": ["warn", { "maxNumericValue": 2000 }], + "interactive": ["warn", { "maxNumericValue": 4000 }] + } + }, + "upload": { + "target": "filesystem", + "outputDir": "lhci-results" + } + } +} diff --git a/.runner b/.runner new file mode 100644 index 0000000..eb78c5c --- /dev/null +++ b/.runner @@ -0,0 +1,12 @@ +{ + "WARNING": "This file is automatically generated by act-runner. Do not edit it manually unless you know what you are doing. Removing this file will cause act runner to re-register as a new runner.", + "id": 11, + "uuid": "e2bf20b6-d8b7-43d7-80fd-d0fd14858cb9", + "name": "community-rule-runner-1", + "token": "3f15646e056e9f6e449e036af6039e67b43a63b9", + "address": "https://git.medlab.host", + "labels": [ + "macos-latest:host", + "self-hosted:host" + ] +} diff --git a/.runner.pid b/.runner.pid new file mode 100644 index 0000000..04ed2f1 --- /dev/null +++ b/.runner.pid @@ -0,0 +1 @@ +50608 diff --git a/.storybook/main.github.js b/.storybook/main.github.js deleted file mode 100644 index 7afbb5d..0000000 --- a/.storybook/main.github.js +++ /dev/null @@ -1,35 +0,0 @@ -/** @type { import('@storybook/nextjs-vite').StorybookConfig } */ -const config = { - stories: [ - "../stories/**/*.mdx", - "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)", - ], - addons: [ - "@chromatic-com/storybook", - "@storybook/addon-docs", - "@storybook/addon-onboarding", - "@storybook/addon-a11y", - "@storybook/addon-vitest", - ], - framework: { - name: "@storybook/nextjs-vite", - options: {}, - }, - staticDirs: ["../public"], - managerHead: (head) => `${head}`, - previewHead: (head) => `${head}`, - async viteFinal(cfg) { - // IMPORTANT: Set base path for GitHub Pages sub-path hosting - cfg.base = "/communityrulestorybook/"; - // Ensure esbuild treats .js as JSX during dep pre-bundling - cfg.optimizeDeps ??= {}; - cfg.optimizeDeps.esbuildOptions ??= {}; - cfg.optimizeDeps.esbuildOptions.loader = { - ...(cfg.optimizeDeps.esbuildOptions.loader || {}), - ".js": "jsx", - ".ts": "tsx", - }; - return cfg; - }, -}; -export default config; diff --git a/.storybook/main.js b/.storybook/main.js index 6e3993d..f3814e8 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -5,18 +5,40 @@ const config = { "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)", ], addons: [ - "@chromatic-com/storybook", - "@storybook/addon-docs", - "@storybook/addon-onboarding", + "@storybook/addon-actions", "@storybook/addon-a11y", - "@storybook/addon-vitest", + "@storybook/addon-interactions", + "@chromatic-com/storybook", ], framework: { name: "@storybook/nextjs-vite", options: {}, }, staticDirs: ["../public"], + + // Auto-detect environment and apply appropriate settings + managerHead: (head) => { + // Only add base href for GitHub Pages (when CI=true or specific environment) + if (process.env.CI || process.env.STORYBOOK_BASE_PATH) { + return `${head}`; + } + return head; + }, + + previewHead: (head) => { + // Only add base href for GitHub Pages + if (process.env.CI || process.env.STORYBOOK_BASE_PATH) { + return `${head}`; + } + return head; + }, + async viteFinal(cfg) { + // Set base path for GitHub Pages when needed + if (process.env.CI || process.env.STORYBOOK_BASE_PATH) { + cfg.base = "/communityrulestorybook/"; + } + // Ensure esbuild treats .js as JSX during dep pre-bundling cfg.optimizeDeps ??= {}; cfg.optimizeDeps.esbuildOptions ??= {}; @@ -28,4 +50,5 @@ const config = { return cfg; }, }; + export default config; diff --git a/.storybook/main.local.js b/.storybook/main.local.js deleted file mode 100644 index 6e3993d..0000000 --- a/.storybook/main.local.js +++ /dev/null @@ -1,31 +0,0 @@ -/** @type { import('@storybook/nextjs-vite').StorybookConfig } */ -const config = { - stories: [ - "../stories/**/*.mdx", - "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)", - ], - addons: [ - "@chromatic-com/storybook", - "@storybook/addon-docs", - "@storybook/addon-onboarding", - "@storybook/addon-a11y", - "@storybook/addon-vitest", - ], - framework: { - name: "@storybook/nextjs-vite", - options: {}, - }, - staticDirs: ["../public"], - async viteFinal(cfg) { - // Ensure esbuild treats .js as JSX during dep pre-bundling - cfg.optimizeDeps ??= {}; - cfg.optimizeDeps.esbuildOptions ??= {}; - cfg.optimizeDeps.esbuildOptions.loader = { - ...(cfg.optimizeDeps.esbuildOptions.loader || {}), - ".js": "jsx", - ".ts": "tsx", - }; - return cfg; - }, -}; -export default config; diff --git a/.storybook/preview.github.js b/.storybook/preview.github.js deleted file mode 100644 index 8b6689a..0000000 --- a/.storybook/preview.github.js +++ /dev/null @@ -1,49 +0,0 @@ -import "../app/globals.css"; - -// Import Google Fonts for Storybook -import { Inter, Bricolage_Grotesque, Space_Grotesk } from "next/font/google"; - -const inter = Inter({ - subsets: ["latin"], - weight: ["400", "500", "600", "700"], - variable: "--font-inter", - display: "swap", -}); - -const bricolageGrotesque = Bricolage_Grotesque({ - subsets: ["latin"], - weight: ["400", "500", "700", "800"], - variable: "--font-bricolage-grotesque", - display: "swap", -}); - -const spaceGrotesk = Space_Grotesk({ - subsets: ["latin"], - weight: ["400", "500", "700"], - variable: "--font-space-grotesk", - display: "swap", -}); - -/** @type { import('@storybook/react').Preview } */ -const preview = { - parameters: { - actions: { argTypesRegex: "^on[A-Z].*" }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - }, - decorators: [ - (Story) => ( -
- -
- ), - ], -}; - -export default preview; diff --git a/.storybook/preview.local.js b/.storybook/preview.local.js deleted file mode 100644 index 8b6689a..0000000 --- a/.storybook/preview.local.js +++ /dev/null @@ -1,49 +0,0 @@ -import "../app/globals.css"; - -// Import Google Fonts for Storybook -import { Inter, Bricolage_Grotesque, Space_Grotesk } from "next/font/google"; - -const inter = Inter({ - subsets: ["latin"], - weight: ["400", "500", "600", "700"], - variable: "--font-inter", - display: "swap", -}); - -const bricolageGrotesque = Bricolage_Grotesque({ - subsets: ["latin"], - weight: ["400", "500", "700", "800"], - variable: "--font-bricolage-grotesque", - display: "swap", -}); - -const spaceGrotesk = Space_Grotesk({ - subsets: ["latin"], - weight: ["400", "500", "700"], - variable: "--font-space-grotesk", - display: "swap", -}); - -/** @type { import('@storybook/react').Preview } */ -const preview = { - parameters: { - actions: { argTypesRegex: "^on[A-Z].*" }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - }, - decorators: [ - (Story) => ( -
- -
- ), - ], -}; - -export default preview; diff --git a/README.md b/README.md index b70ece1..d336bd3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A Next.js application for community decision-making and governance documentation. -## Getting Started +## ๐Ÿš€ Getting Started Run the development server: @@ -12,68 +12,170 @@ npm run dev Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. -## Storybook Development +## ๐Ÿงช Testing Framework -This project includes Storybook for component development and documentation. The setup supports both local development and GitHub Pages deployment. +This project includes a comprehensive testing framework with multiple layers of testing: + +### Quick Test Commands + +```bash +# Unit tests with coverage +npm test + +# E2E tests +npm run e2e + +# Performance tests +npm run lhci + +# Storybook tests +npm run test:sb +``` + +### Test Coverage + +- โœ… **124 Unit Tests** (8 components + 1 integration) +- โœ… **308 E2E Tests** (4 browsers ร— 77 tests) +- โœ… **92 Visual Regression Screenshots** +- โœ… **Performance Budgets** +- โœ… **Accessibility Compliance** + +### CI/CD Pipeline + +- **Gitea Actions** with 7 parallel jobs +- **Cross-browser testing** (Chromium, Firefox, WebKit, Mobile) +- **Visual regression testing** +- **Performance monitoring** +- **Code coverage reporting** + +๐Ÿ“– **For detailed testing documentation, see [docs/TESTING.md](docs/TESTING.md)** + +## ๐Ÿ“š Storybook Development + +This project includes Storybook for component development and documentation. The setup automatically detects the environment and applies the appropriate configuration. ### Local Development -For local Storybook development (no base path): +For local Storybook development: ```bash npm run storybook:local +# or simply +npm run storybook ``` This will: -- Copy local configuration files (without GitHub Pages base path) - Start Storybook at `http://localhost:6006` -- Ignore configuration changes in git +- Use relative paths for assets (no base path) -### Production Deployment +### GitHub Pages Deployment -When ready to deploy to GitHub Pages: +For GitHub Pages deployment with base path: -1. **Restore GitHub Pages configuration:** +```bash +npm run storybook:build:github +``` - ```bash - npm run storybook:restore - ``` +This will: -2. **Build Storybook:** +- Build Storybook with `/communityrulestorybook/` base path +- Generate files ready for GitHub Pages deployment - ```bash - npm run build-storybook - ``` +### CI/CD Integration -3. **Deploy to GitHub Pages repository:** +The CI pipeline automatically uses the GitHub Pages configuration when building Storybook. - ```bash - # Copy the build to your GitHub Pages repository - cp -r storybook-static/* /path/to/communityrulestorybook/ +### Configuration - # Or if you have it as a git submodule: - cp -r storybook-static/* communityrulestorybook/ - cd communityrulestorybook - git add . - git commit -m "Update Storybook build" - git push origin main - ``` +The Storybook configuration automatically detects the environment: -### Switching Between Configurations +- **Local development**: No base path, relative assets +- **CI/Production**: Base path `/communityrulestorybook/` for GitHub Pages -- **Local Development:** `npm run storybook:local` -- **Production Build:** `npm run storybook:restore` then `npm run build-storybook` -- **Back to Local:** `npm run storybook:local` +## ๐Ÿ“‹ Available Scripts -The gitignore is configured to prevent configuration file changes from triggering git changes during local development. - -### Available Scripts +### Development - `npm run dev` - Start Next.js development server - `npm run build` - Build Next.js application for production - `npm run start` - Start Next.js production server -- `npm run storybook:local` - Start Storybook with local configuration -- `npm run storybook:restore` - Restore GitHub Pages configuration -- `npm run build-storybook` - Build Storybook for production + +### Testing + +- `npm test` - Run unit tests with coverage +- `npm run test:watch` - Run tests in watch mode +- `npm run test:ui` - Run tests with UI +- `npm run e2e` - Run E2E tests +- `npm run e2e:ui` - Run E2E tests with UI +- `npm run e2e:serve` - Start dev server and run E2E tests +- `npm run lhci` - Run performance tests +- `npm run test:sb` - Run Storybook tests + +### Storybook + +- `npm run storybook:local` - Start Storybook for local development +- `npm run storybook:github` - Start Storybook with GitHub Pages configuration +- `npm run storybook:build` - Build Storybook for local deployment +- `npm run storybook:build:github` - Build Storybook for GitHub Pages - `npm run storybook` - Start Storybook with current configuration + +## ๐Ÿ—๏ธ Project Structure + +``` +community-rule/ +โ”œโ”€โ”€ app/ # Next.js app directory +โ”‚ โ”œโ”€โ”€ components/ # React components +โ”‚ โ”œโ”€โ”€ layout.js # Root layout +โ”‚ โ””โ”€โ”€ page.js # Homepage +โ”œโ”€โ”€ tests/ # Test files +โ”‚ โ”œโ”€โ”€ unit/ # Unit tests (8 components) +โ”‚ โ”œโ”€โ”€ integration/ # Integration tests +โ”‚ โ””โ”€โ”€ e2e/ # E2E tests (4 test suites) +โ”œโ”€โ”€ docs/ # Documentation +โ”‚ โ””โ”€โ”€ TESTING.md # Comprehensive testing guide +โ”œโ”€โ”€ .storybook/ # Storybook configuration +โ”œโ”€โ”€ .gitea/ # Gitea Actions workflows +โ”‚ โ””โ”€โ”€ workflows/ +โ”‚ โ””โ”€โ”€ ci.yml # CI/CD pipeline +โ””โ”€โ”€ public/ # Static assets +``` + +## ๐Ÿ”ง Technology Stack + +- **Framework**: Next.js 15 + React 19 +- **Styling**: Tailwind CSS 4 +- **Testing**: Vitest + Playwright + Lighthouse CI +- **Documentation**: Storybook 9 +- **CI/CD**: Gitea Actions +- **Hosting**: Gitea (Git hosting) + +## ๐Ÿ“– Documentation + +- **[Testing Framework](docs/TESTING.md)** - Comprehensive testing guide +- **[Storybook](http://localhost:6006)** - Component documentation (local) +- **[GitHub Pages Storybook](https://your-username.github.io/communityrulestorybook/)** - Public component docs + +## ๐Ÿค Contributing + +1. **Fork the repository** +2. **Create a feature branch**: `git checkout -b feature/amazing-feature` +3. **Write tests first** (see [Testing Guide](docs/TESTING.md)) +4. **Make your changes** +5. **Run tests**: `npm test && npm run e2e` +6. **Commit changes**: `git commit -m "feat: add amazing feature"` +7. **Push to branch**: `git push origin feature/amazing-feature` +8. **Create Pull Request** + +### Development Workflow + +- All changes must have tests +- CI pipeline runs automatically on PRs +- Visual regression tests ensure UI consistency +- Performance budgets must be met +- Accessibility standards must be maintained + +## ๐Ÿ“„ License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. +# Test trigger diff --git a/TESTING_STRATEGY.md b/TESTING_STRATEGY.md new file mode 100644 index 0000000..d22c79d --- /dev/null +++ b/TESTING_STRATEGY.md @@ -0,0 +1,258 @@ +# Testing Strategy for CommunityRule + +## Overview + +This document outlines our comprehensive testing strategy that properly separates unit testing from responsive behavior testing, following best practices for JSDOM limitations and real browser testing. + +## Current Test Status + +- **236 total tests** across the project +- **227 tests passing** (96.2% success rate) +- **9 tests failing** (performance and interaction tests) +- **15 test files** covering all major components +- **Performance Monitoring**: Comprehensive regression detection and budget enforcement + +## Testing Philosophy + +### The Problem with JSDOM and Responsive Testing + +**Short take: Unit tests in JSDOM can't truly "switch breakpoints."** JSDOM doesn't evaluate CSS media queries, so Tailwind's `hidden sm:block โ€ฆ` won't change visibility when you "resize" the window. + +### Solution: Proper Test Separation + +- **Unit / component tests (Vitest + RTL):** assert **structure and classes**, not responsive visibility. +- **Responsive behavior:** verify with **browser-based tests** (Playwright) or **visual tests** (Chromatic/Storybook) at real viewport widths. + +## Test Categories + +### 1. Unit Tests (Vitest + React Testing Library) + +**Purpose:** Test component structure, accessibility, and configuration data. + +**What to test:** + +- DOM roles/labels exist: `role="banner"`, nav landmark, menu items +- The right **Tailwind classes** are present on wrappers (`block sm:hidden`, `hidden md:block`, etc.) +- Data-driven bits produce the expected count/order (e.g., `navigationItems`, `avatarImages`, `logoConfig`) +- Component configuration and exported data structures + +**Example:** + +```javascript +// tests/unit/Header.structure.test.js +test("logo wrappers include breakpoint classes", () => { + render(
); + const logoWrappers = screen.getAllByTestId("logo-wrapper"); + + // Check first logo variant (xs only) + expect(logoWrappers[0]).toHaveClass("block", "sm:hidden"); + + // Check second logo variant (sm only) + expect(logoWrappers[1]).toHaveClass("hidden", "sm:block", "md:hidden"); +}); +``` + +### 2. Browser-Based Tests (Playwright) + +**Purpose:** Test real responsive behavior at actual viewport widths. + +**What to test:** + +- **Visibility** at real breakpoints +- **Layout changes** between breakpoints +- **Interactive behavior** at different screen sizes +- **Accessibility** across viewports + +**Example:** + +```javascript +// tests/e2e/header.responsive.spec.js +const breakpoints = [ + { name: "xs", width: 360, height: 700 }, + { name: "sm", width: 640, height: 700 }, + { name: "md", width: 768, height: 700 }, + { name: "lg", width: 1024, height: 700 }, + { name: "xl", width: 1280, height: 700 }, +]; + +for (const bp of breakpoints) { + test(`header layout at ${bp.name}`, async ({ page }) => { + await page.setViewportSize({ width: bp.width, height: bp.height }); + await page.goto("/"); + + const nav = page.getByRole("navigation", { name: /main navigation/i }); + await expect(nav).toBeVisible(); + }); +} +``` + +### 3. Visual Tests (Storybook + Chromatic) + +**Purpose:** Visual regression testing and design system validation. + +**What to test:** + +- **Visual diffs** per breakpoint +- **Design consistency** across viewports +- **Component variations** and states + +**Example:** + +```javascript +// stories/Header.responsive.stories.js +export default { + parameters: { + chromatic: { + viewports: [360, 640, 768, 1024, 1280], + delay: 100, + }, + }, +}; +``` + +## Component Improvements + +### Header Component Enhancements + +1. **Added Test IDs** for easier testing: + + ```jsx +
+ {renderLogo(config.size, config.showText)} +
+ ``` + +2. **Exported Configuration** for testing: + + ```javascript + export const navigationItems = [...]; + export const avatarImages = [...]; + export const logoConfig = [...]; + ``` + +3. **Structured Breakpoint Containers**: + ```jsx +
+
+
+ ``` + +## Test File Structure + +``` +tests/ +โ”œโ”€โ”€ unit/ # Unit tests (Vitest + RTL) +โ”‚ โ”œโ”€โ”€ Header.test.jsx # CONSOLIDATED: Comprehensive Header tests +โ”‚ โ”œโ”€โ”€ Footer.test.jsx +โ”‚ โ”œโ”€โ”€ Layout.test.jsx +โ”‚ โ””โ”€โ”€ Page.test.jsx +โ”œโ”€โ”€ integration/ # Integration tests +โ”‚ โ””โ”€โ”€ ContentLockup.integration.test.jsx +โ”œโ”€โ”€ e2e/ # Browser tests (Playwright) +โ”‚ โ””โ”€โ”€ header.responsive.spec.js # NEW: Responsive behavior tests +โ””โ”€โ”€ stories/ # Storybook stories + โ””โ”€โ”€ Header.responsive.stories.js # NEW: Visual testing +``` + +## Best Practices + +### Unit Testing (JSDOM) + +1. **Test structure, not visibility**: + + ```javascript + // โœ… Good: Test classes exist + expect(element).toHaveClass("block", "sm:hidden"); + + // โŒ Bad: Test visibility (doesn't work in JSDOM) + expect(element).toBeVisible(); + ``` + +2. **Use test IDs for containers**: + + ```javascript + // โœ… Good: Test specific containers + const logoWrapper = screen.getByTestId("logo-wrapper"); + + // โŒ Bad: Query by complex class strings + const logoWrapper = document.querySelector(".block.sm\\:hidden"); + ``` + +3. **Test configuration data**: + ```javascript + // โœ… Good: Test exported configuration + expect(navigationItems).toHaveLength(3); + expect(logoConfig).toHaveLength(5); + ``` + +### Browser Testing (Playwright) + +1. **Test real viewport sizes**: + + ```javascript + await page.setViewportSize({ width: 640, height: 700 }); + ``` + +2. **Test visibility at breakpoints**: + + ```javascript + if (bp.name === "xs") { + await expect(page.getByTestId("auth-xs")).toBeVisible(); + } + ``` + +3. **Test accessibility across viewports**: + + ```javascript + const interactiveElements = [ + page.getByRole("link", { name: /use cases/i }), + page.getByRole("button", { name: /create rule/i }), + ]; + + for (const element of interactiveElements) { + await expect(element).toBeVisible(); + await expect(element).toBeEnabled(); + } + ``` + +## Running Tests + +### Unit Tests + +```bash +npm test # Run all unit tests +npm test tests/unit/ # Run only unit tests +npm test Header.structure # Run specific test file +``` + +### Browser Tests + +```bash +npx playwright test # Run all browser tests +npx playwright test header.responsive.spec.js # Run specific test +``` + +### Visual Tests + +```bash +npm run storybook # Start Storybook +npx chromatic --project-token=xxx # Run visual tests +``` + +## Future Improvements + +1. **Add more Playwright tests** for other components +2. **Set up Chromatic** for visual regression testing +3. **Add performance tests** for responsive behavior +4. **Create component-specific test utilities** +5. **Add accessibility testing** with axe-core + +## Key Takeaways + +1. **JSDOM limitations** require separating structure tests from visibility tests +2. **Test IDs** make testing more reliable and maintainable +3. **Exported configuration** enables better data structure testing +4. **Real browser testing** is essential for responsive behavior +5. **Visual testing** catches design regressions across breakpoints + +This strategy provides comprehensive coverage while respecting the limitations of different testing environments. diff --git a/act_runner b/act_runner new file mode 100755 index 0000000..e7f54f2 Binary files /dev/null and b/act_runner differ diff --git a/app/components/Header.js b/app/components/Header.js index 0579285..70de0bc 100644 --- a/app/components/Header.js +++ b/app/components/Header.js @@ -5,6 +5,35 @@ import Button from "./Button"; import AvatarContainer from "./AvatarContainer"; import Avatar from "./Avatar"; +// Configuration data for testing +export const navigationItems = [ + { href: "#", text: "Use cases", extraPadding: true }, + { href: "#", text: "Learn" }, + { href: "#", text: "About" }, +]; + +export const avatarImages = [ + { src: "assets/Avatar_1.png", alt: "Avatar 1" }, + { src: "assets/Avatar_2.png", alt: "Avatar 2" }, + { src: "assets/Avatar_3.png", alt: "Avatar 3" }, +]; + +export const logoConfig = [ + { breakpoint: "block sm:hidden", size: "header", showText: false }, + { breakpoint: "hidden sm:block md:hidden", size: "header", showText: true }, + { + breakpoint: "hidden md:block lg:hidden", + size: "headerMd", + showText: true, + }, + { + breakpoint: "hidden lg:block xl:hidden", + size: "headerLg", + showText: true, + }, + { breakpoint: "hidden xl:block", size: "headerXl", showText: true }, +]; + export default function Header({ onToggle }) { // Schema markup for site navigation const schemaData = { @@ -18,33 +47,6 @@ export default function Header({ onToggle }) { "query-input": "required name=search_term_string", }, }; - const navigationItems = [ - { href: "#", text: "Use cases", extraPadding: true }, - { href: "#", text: "Learn" }, - { href: "#", text: "About" }, - ]; - - const avatarImages = [ - { src: "assets/Avatar_1.png", alt: "Avatar 1" }, - { src: "assets/Avatar_2.png", alt: "Avatar 2" }, - { src: "assets/Avatar_3.png", alt: "Avatar 3" }, -]; - - const logoConfig = [ - { breakpoint: "block sm:hidden", size: "header", showText: false }, - { breakpoint: "hidden sm:block md:hidden", size: "header", showText: true }, - { - breakpoint: "hidden md:block lg:hidden", - size: "headerMd", - showText: true, - }, - { - breakpoint: "hidden lg:block xl:hidden", - size: "headerLg", - showText: true, - }, - { breakpoint: "hidden xl:block", size: "headerXl", showText: true }, - ]; const renderNavigationItems = (size) => { return navigationItems.map((item, index) => ( @@ -118,7 +120,11 @@ export default function Header({ onToggle }) { {/* Logo - Consistent left positioning across all breakpoints */}
{logoConfig.map((config, index) => ( -
+
{renderLogo(config.size, config.showText)}
))} @@ -127,29 +133,29 @@ export default function Header({ onToggle }) { {/* Navigation Links - Consistent center positioning */}
{/* XSmall breakpoint - Navigation items moved to right section */} -
+
{/* Empty for XSmall - navigation moved to right */}
{/* Small breakpoint - All items grouped together, centered */} -
+
{renderNavigationItems("xsmall")} {renderLoginButton("xsmall")}
-
+
{renderNavigationItems("xsmall")}
-
+
{renderNavigationItems("large")}
-
+
{renderNavigationItems("xlarge")}
@@ -157,41 +163,43 @@ export default function Header({ onToggle }) { {/* Authentication Elements - Consistent right alignment across all breakpoints */}
{/* XSmall breakpoint - All navigation items + Create Rule button */} -
+
- {renderNavigationItems("xsmall")} - {renderLoginButton("xsmall")} + + {renderNavigationItems("xsmall")} + {renderLoginButton("xsmall")} + {renderCreateRuleButton("xsmall", "small", "small")}
{/* Small breakpoint - Only Create Rule button */} -
+
{renderCreateRuleButton("xsmall", "small", "small")}
{/* Medium breakpoint */} -
+
- {renderLoginButton("xsmall")} + {renderLoginButton("xsmall")} {renderCreateRuleButton("xsmall", "medium", "medium")}
{/* Large breakpoint */} -
+
- {renderLoginButton("large")} + {renderLoginButton("large")} {renderCreateRuleButton("large", "xlarge", "xlarge")}
{/* XLarge breakpoint */} -
+
- {renderLoginButton("xlarge")} + {renderLoginButton("xlarge")} {renderCreateRuleButton("xlarge", "xlarge", "xlarge")}
diff --git a/app/components/Logo.js b/app/components/Logo.js index ae8b8ac..8b7e83d 100644 --- a/app/components/Logo.js +++ b/app/components/Logo.js @@ -117,7 +117,7 @@ export default function Logo({ size = "default", showText = true }) { className={`flex items-center ${config.containerHeight} ${ showText ? config.gap : "" } transition-all duration-200 ease-in-out hover:scale-[1.02] cursor-pointer`} - role="banner" + role="link" aria-label="CommunityRule Logo" > {/* Logo Text - only show if showText is true */} diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..7d9f0c3 --- /dev/null +++ b/config.yaml @@ -0,0 +1,34 @@ +log: + level: info + +runner: + file: .runner + capacity: 2 + timeout: 3h + insecure: false + fetch_timeout: 5s + fetch_interval: 2s + labels: + - "macos-latest:host" + - "self-hosted:host" + +cache: + enabled: true + dir: "" + host: "" + port: 0 + external_server: "" + +container: + network: "" + privileged: false + options: + workdir_parent: + valid_volumes: [] + docker_host: "" + force_pull: false + # Use host environment instead of containers + mode: "host" + +host: + workdir_parent: "" diff --git a/docs/PERFORMANCE_MONITORING.md b/docs/PERFORMANCE_MONITORING.md new file mode 100644 index 0000000..f5dbf37 --- /dev/null +++ b/docs/PERFORMANCE_MONITORING.md @@ -0,0 +1,319 @@ +# Performance Monitoring System + +## Overview + +The Community Rule platform includes a comprehensive performance monitoring system designed to detect performance regressions, maintain performance budgets, and ensure optimal user experience across all components and user interactions. + +## Architecture + +### Core Components + +1. **Performance Monitor Module** (`tests/performance/performance-monitor.js`) + + - Base `PerformanceMonitor` class for metric collection and analysis + - `WebPerformanceMonitor` for browser-based performance monitoring + - `PlaywrightPerformanceMonitor` for E2E performance testing + +2. **Performance Tests** (`tests/e2e/performance.spec.ts`) + + - Comprehensive E2E performance tests using Playwright + - Core Web Vitals monitoring + - Component render performance testing + - Interaction performance testing + +3. **Lighthouse CI Integration** (`lighthouserc.json`) + + - Automated performance audits + - Performance budget enforcement + - Core Web Vitals validation + +4. **Performance Budgets** (`performance-budgets.json`) + + - Resource size limits + - Timing budgets + - Resource count limits + +5. **Monitoring Script** (`scripts/performance-monitor.js`) + - Standalone performance monitoring + - Regression detection + - Report generation + +## Performance Budgets + +### Timing Budgets + +| Metric | Budget | Baseline | Description | +| ------------------------ | ------ | -------- | ------------------------- | +| Page Load Time | 3000ms | 2000ms | Total page load time | +| First Contentful Paint | 2000ms | 1500ms | First content appears | +| Largest Contentful Paint | 2500ms | 2000ms | Largest content element | +| First Input Delay | 100ms | 50ms | First user interaction | +| TTFB | 600ms | 400ms | Time to First Byte | +| Component Render | 500ms | 300ms | Component rendering time | +| Interaction Time | 100ms | 50ms | User interaction response | +| Scroll Performance | 50ms | 30ms | Scroll operation time | + +### Resource Budgets + +| Resource Type | Size Limit | Count Limit | Description | +| ------------- | ---------- | ----------- | ---------------------- | +| Scripts | 300KB | 10 | JavaScript files | +| Stylesheets | 50KB | 5 | CSS files | +| Images | 100KB | 20 | Image files | +| Fonts | 50KB | 5 | Font files | +| Total | 500KB | 50 | All resources combined | + +## Usage + +### Running Performance Tests + +```bash +# Run all performance tests +npm run e2e:performance + +# Run specific performance test +npx playwright test tests/e2e/performance.spec.ts --grep="homepage load performance" + +# Run with specific browser +npx playwright test tests/e2e/performance.spec.ts --project=chromium +``` + +### Running Lighthouse CI + +```bash +# Run Lighthouse CI with default settings +npm run lhci + +# Run with mobile preset +npm run lhci:mobile + +# Run with desktop preset +npm run lhci:desktop + +# Run with performance budgets +npm run performance:budget +``` + +### Running Performance Monitoring + +```bash +# Run comprehensive performance monitoring +npm run performance:monitor + +# Run monitoring script directly +node scripts/performance-monitor.js +``` + +## Performance Metrics + +### Core Web Vitals + +1. **Largest Contentful Paint (LCP)** + + - Measures loading performance + - Target: < 2.5 seconds + - Baseline: < 2.0 seconds + +2. **First Input Delay (FID)** + + - Measures interactivity + - Target: < 100ms + - Baseline: < 50ms + +3. **Cumulative Layout Shift (CLS)** + - Measures visual stability + - Target: < 0.1 + - Baseline: < 0.05 + +### Navigation Timing + +- **DNS Lookup**: Domain name resolution time +- **TCP Connection**: Connection establishment time +- **TTFB**: Time to First Byte +- **Download**: Resource download time +- **DOM Content Loaded**: DOM parsing completion +- **Load**: Full page load completion + +### Component Performance + +- **Render Time**: Component rendering duration +- **Interaction Time**: User interaction response time +- **Scroll Performance**: Smooth scrolling performance +- **Memory Usage**: JavaScript heap memory consumption + +## Regression Detection + +### Automatic Detection + +The performance monitoring system automatically detects regressions by: + +1. **Comparing against baselines**: Current metrics vs. established baselines +2. **Threshold monitoring**: Real-time threshold violation detection +3. **Trend analysis**: Performance degradation over time +4. **Statistical analysis**: Variance and consistency monitoring + +### Regression Thresholds + +- **20% degradation**: Triggers regression warning +- **50% degradation**: Triggers regression error +- **Consistent degradation**: Pattern-based regression detection + +### Alert System + +```javascript +// Example regression detection output +๐Ÿšจ Performance regression detected: scroll_performance = 111ms (baseline: 30ms) +โš ๏ธ Performance threshold exceeded: interaction_time = 1368ms (threshold: 100ms) +``` + +## Performance Reports + +### Generated Reports + +1. **Console Output**: Real-time performance metrics and warnings +2. **JSON Reports**: Structured performance data (`performance-report.json`) +3. **Lighthouse Reports**: Detailed performance audits +4. **Playwright Reports**: E2E test results with performance data + +### Report Structure + +```json +{ + "timestamp": "2024-01-01T12:00:00.000Z", + "summary": { + "totalMetrics": 15, + "regressions": 2, + "warnings": 3 + }, + "regressions": [ + { + "metric": "scroll_performance", + "current": 111, + "baseline": 30, + "regression": "270.0%" + } + ], + "warnings": [ + "Performance threshold exceeded: interaction_time = 1368ms (threshold: 100ms)" + ], + "metrics": { + "page_load_time": { + "latest": 1704, + "average": 1704, + "min": 1704, + "max": 1704, + "count": 1 + } + } +} +``` + +## CI/CD Integration + +### GitHub Actions Integration + +```yaml +# Example CI workflow +- name: Performance Tests + run: | + npm run e2e:performance + npm run lhci + npm run performance:budget +``` + +### Performance Gates + +- **Performance Score**: Must be > 90 +- **Core Web Vitals**: All metrics within budgets +- **Regression Detection**: No significant regressions +- **Resource Budgets**: All resources within limits + +## Best Practices + +### Development Workflow + +1. **Pre-commit Checks**: Run performance tests before commits +2. **Baseline Updates**: Update baselines after performance improvements +3. **Budget Reviews**: Regular budget review and adjustment +4. **Regression Investigation**: Immediate investigation of detected regressions + +### Performance Optimization + +1. **Code Splitting**: Implement dynamic imports for better loading +2. **Image Optimization**: Use modern formats and proper sizing +3. **Caching**: Implement effective caching strategies +4. **Bundle Analysis**: Regular bundle size monitoring + +### Monitoring Strategy + +1. **Continuous Monitoring**: Automated performance testing in CI/CD +2. **Real User Monitoring**: Collect performance data from real users +3. **Alert Thresholds**: Set appropriate alert thresholds +4. **Performance Budgets**: Enforce strict performance budgets + +## Troubleshooting + +### Common Issues + +1. **Test Timeouts** + + - Increase timeout values for slow operations + - Add proper wait conditions + - Check for network issues + +2. **False Positives** + + - Adjust baseline values + - Review test environment + - Check for external dependencies + +3. **Performance Fluctuations** + - Run multiple test iterations + - Use statistical analysis + - Consider environmental factors + +### Debugging Performance Issues + +```bash +# Enable detailed logging +DEBUG=playwright:* npm run e2e:performance + +# Run with specific browser and debugging +npx playwright test tests/e2e/performance.spec.ts --project=chromium --debug + +# Generate detailed reports +npm run performance:monitor -- --verbose +``` + +## Future Enhancements + +### Planned Features + +1. **Real User Monitoring (RUM)** + + - Collect performance data from real users + - User-centric performance metrics + - Geographic performance analysis + +2. **Advanced Analytics** + + - Machine learning-based regression detection + - Predictive performance modeling + - Automated performance optimization suggestions + +3. **Performance Dashboard** + + - Web-based performance monitoring dashboard + - Real-time performance metrics visualization + - Historical performance trends + +4. **Integration with APM Tools** + - New Relic integration + - DataDog integration + - Custom APM tool integration + +## Conclusion + +The performance monitoring system provides comprehensive coverage of application performance, enabling early detection of regressions and maintaining high performance standards. Regular monitoring and proactive optimization ensure optimal user experience across all platforms and devices. + +For questions or issues with the performance monitoring system, please refer to the testing documentation or create an issue in the project repository. diff --git a/docs/SNAPSHOT_WORKFLOW.md b/docs/SNAPSHOT_WORKFLOW.md new file mode 100644 index 0000000..01d8227 --- /dev/null +++ b/docs/SNAPSHOT_WORKFLOW.md @@ -0,0 +1,110 @@ +# Visual Regression Snapshot Workflow + +Quick reference for managing visual regression snapshots. + +## ๐Ÿš€ **First-Time Setup** + +```bash +# 1. Generate baseline snapshots (choose one) +npm run seed-snapshots # Docker (recommended for CI consistency) +npm run seed-snapshots:local # Local environment + +# 2. Commit the snapshots +git add tests/e2e/visual-regression.spec.ts-snapshots/ +git commit -m "Add baseline visual regression snapshots" + +# 3. Verify setup +npm run visual:test +``` + +## ๐Ÿ”„ **Daily Workflow** + +```bash +# Run visual regression tests +npm run visual:test + +# Run with UI for debugging +npm run visual:ui + +# Update snapshots after UI changes +npm run visual:update +``` + +## ๐Ÿ“ **When UI Changes** + +1. **Make your UI changes** (design updates, component modifications, etc.) + +2. **Update snapshots to reflect new design:** + + ```bash + npm run visual:update + ``` + +3. **Review changes:** + + ```bash + git diff tests/e2e/visual-regression.spec.ts-snapshots/ + ``` + +4. **Commit updated snapshots:** + ```bash + git add tests/e2e/visual-regression.spec.ts-snapshots/ + git commit -m "Update snapshots for [describe changes]" + ``` + +## ๐Ÿ› **Troubleshooting** + +### **"Snapshot doesn't exist" errors** + +- **Cause**: Baseline snapshots haven't been generated +- **Fix**: Run `npm run seed-snapshots:local` + +### **Platform differences (macOS vs Linux)** + +- **Cause**: Different font rendering between platforms +- **Fix**: Use `npm run seed-snapshots` (Docker container) + +### **Minor pixel differences** + +- **Cause**: Font rendering, anti-aliasing differences +- **Fix**: Check tolerance settings in `playwright.config.ts` + +### **Animation-related failures** + +- **Cause**: Animations not fully disabled +- **Fix**: Ensure `animations: "disabled"` is set (already configured) + +## ๐Ÿ“ **File Structure** + +``` +tests/e2e/ +โ”œโ”€โ”€ visual-regression.spec.ts # Test definitions +โ””โ”€โ”€ visual-regression.spec.ts-snapshots/ # Baseline images + โ”œโ”€โ”€ homepage-full-chromium.png + โ”œโ”€โ”€ homepage-viewport-chromium.png + โ”œโ”€โ”€ hero-banner-chromium.png + โ””โ”€โ”€ ... +``` + +## โšก **Quick Commands Reference** + +| Command | Purpose | +| ------------------------------ | ----------------------------------------------- | +| `npm run visual:test` | Run visual regression tests | +| `npm run visual:update` | Update snapshots after UI changes | +| `npm run visual:ui` | Run tests with UI for debugging | +| `npm run seed-snapshots` | Generate baselines with Docker (CI consistency) | +| `npm run seed-snapshots:local` | Generate baselines locally | + +## ๐Ÿ’ก **Best Practices** + +1. **Always review changes** before committing updated snapshots +2. **Use descriptive commit messages** when updating snapshots +3. **Test locally first** before pushing to CI +4. **Use Docker for consistency** when generating baselines +5. **Update snapshots promptly** after UI changes to avoid drift + +## ๐Ÿ”— **Related Documentation** + +- [Visual Regression Setup](./VISUAL_REGRESSION_SETUP.md) - Detailed setup guide +- [Testing Strategy](../TESTING_STRATEGY.md) - Overall testing approach diff --git a/docs/TESTING.md b/docs/TESTING.md new file mode 100644 index 0000000..6c3c9b4 --- /dev/null +++ b/docs/TESTING.md @@ -0,0 +1,701 @@ +# Testing Framework Documentation + +## ๐Ÿ“‹ Table of Contents + +- [Overview](#overview) +- [Quick Start](#quick-start) +- [Test Structure](#test-structure) +- [Unit & Integration Testing](#unit--integration-testing) +- [E2E Testing](#e2e-testing) +- [Visual Regression Testing](#visual-regression-testing) +- [Performance Testing](#performance-testing) +- [Storybook Testing](#storybook-testing) +- [CI/CD Pipeline](#cicd-pipeline) +- [Development Workflow](#development-workflow) +- [Best Practices](#best-practices) +- [Troubleshooting](#troubleshooting) +- [Monitoring & Metrics](#monitoring--metrics) + +## ๐ŸŽฏ Overview + +This project uses a comprehensive testing framework with multiple layers of testing to ensure code quality, functionality, and visual consistency across all browsers and devices. + +### Testing Stack + +- **Unit/Integration**: Vitest + JSDOM + React Testing Library +- **E2E**: Playwright (Chromium, Firefox, WebKit, Mobile) +- **Visual Regression**: Playwright Screenshots +- **Performance**: Lighthouse CI +- **Accessibility**: Axe-core + Storybook +- **CI/CD**: Gitea Actions + +### Test Coverage + +- โœ… **124 Unit Tests** (8 components + 1 integration) +- โœ… **308 E2E Tests** (4 browsers ร— 77 tests) +- โœ… **92 Visual Regression Screenshots** +- โœ… **Performance Budgets** +- โœ… **Accessibility Compliance** + +## ๐Ÿš€ Quick Start + +### Prerequisites + +```bash +# Install dependencies +npm install + +# Install Playwright browsers +npx playwright install +``` + +### Running Tests + +```bash +# All unit tests with coverage +npm test + +# Unit tests in watch mode +npm run test:watch + +# E2E tests +npm run e2e + +# Performance tests +npm run lhci + +# Storybook tests +npm run test:sb +``` + +## ๐Ÿ“ Test Structure + +``` +tests/ +โ”œโ”€โ”€ unit/ # Component unit tests +โ”‚ โ”œโ”€โ”€ Button.test.jsx # 113 lines +โ”‚ โ”œโ”€โ”€ HeroBanner.test.jsx # 143 lines +โ”‚ โ”œโ”€โ”€ FeatureGrid.test.jsx # 146 lines +โ”‚ โ”œโ”€โ”€ LogoWall.test.jsx # 170 lines +โ”‚ โ”œโ”€โ”€ NumberedCards.test.jsx # 196 lines +โ”‚ โ”œโ”€โ”€ RuleStack.test.jsx # 207 lines +โ”‚ โ”œโ”€โ”€ QuoteBlock.test.jsx # 223 lines +โ”‚ โ””โ”€โ”€ AskOrganizer.test.jsx # 294 lines +โ”œโ”€โ”€ integration/ # Component integration tests +โ”‚ โ””โ”€โ”€ ContentLockup.integration.test.jsx # 157 lines +โ””โ”€โ”€ e2e/ # End-to-end tests + โ”œโ”€โ”€ homepage.spec.ts # 18 tests per browser + โ”œโ”€โ”€ user-journeys.spec.ts # 13 tests per browser + โ”œโ”€โ”€ edge-cases.spec.ts # 18 tests per browser + โ””โ”€โ”€ visual-regression.spec.ts # 23 tests per browser +``` + +## ๐Ÿš€ Runner Management Scripts + +``` +community-rule/ +โ”œโ”€โ”€ start-runner.sh # Start Gitea Actions runner +โ”œโ”€โ”€ stop-runner.sh # Stop Gitea Actions runner +โ”œโ”€โ”€ status-runner.sh # Check runner status +โ”œโ”€โ”€ config.yaml # Runner configuration +โ””โ”€โ”€ act_runner # Gitea Actions runner binary +``` + +## ๐Ÿงช Unit & Integration Testing + +### Framework + +- **Vitest**: Fast unit test runner +- **JSDOM**: Browser environment simulation +- **React Testing Library**: Component testing utilities +- **MSW**: API mocking + +### Configuration + +```javascript +// vitest.config.js +export default defineConfig({ + plugins: [react({ jsxRuntime: "automatic" })], + test: { + environment: "jsdom", + setupFiles: ["./vitest.setup.js"], + coverage: { + provider: "v8", + thresholds: { lines: 85, functions: 85, statements: 85, branches: 80 }, + }, + }, +}); +``` + +### Writing Unit Tests + +```jsx +// tests/unit/Component.test.jsx +import { render, screen } from "@testing-library/react"; +import { describe, test, expect, afterEach } from "vitest"; +import { cleanup } from "@testing-library/react"; +import Component from "../../app/components/Component"; + +describe("Component", () => { + afterEach(() => cleanup()); + + test("renders correctly", () => { + render(); + expect(screen.getByRole("button")).toBeInTheDocument(); + }); +}); +``` + +### Available Scripts + +```bash +npm test # Run all tests with coverage +npm run test:watch # Run tests in watch mode +npm run test:ui # Run tests with UI +``` + +## ๐ŸŒ E2E Testing + +### Framework + +- **Playwright**: Cross-browser E2E testing +- **Browsers**: Chromium, Firefox, WebKit, Mobile +- **Accessibility**: Axe-core integration + +### Configuration + +```typescript +// playwright.config.ts +export default defineConfig({ + testDir: "./tests/e2e", + projects: [ + { name: "chromium", use: { ...devices["Desktop Chrome"] } }, + { name: "firefox", use: { ...devices["Desktop Firefox"] } }, + { name: "webkit", use: { ...devices["Desktop Safari"] } }, + { name: "mobile", use: { ...devices["iPhone 12"] } }, + ], +}); +``` + +### Test Categories + +#### 1. Homepage Tests (18 tests per browser) + +- Page loading and sections +- Component functionality +- Navigation and interactions +- Responsive design +- Accessibility compliance +- Performance metrics + +#### 2. User Journey Tests (13 tests per browser) + +- Complete user workflows +- Feature exploration +- Contact flows +- Learning paths +- Navigation patterns + +#### 3. Edge Cases Tests (18 tests per browser) + +- Network conditions +- Browser behavior +- Error scenarios +- Accessibility edge cases +- Performance under stress + +#### 4. Visual Regression Tests (23 tests per browser) + +- Full page screenshots +- Component screenshots +- Responsive screenshots +- Interactive states + +### Writing E2E Tests + +```typescript +// tests/e2e/example.spec.ts +import { test, expect } from "@playwright/test"; + +test.describe("Feature", () => { + test.beforeEach(async ({ page }) => { + await page.goto("/"); + }); + + test("should work correctly", async ({ page }) => { + await expect(page).toHaveTitle(/CommunityRule/); + await expect(page.locator("h1")).toBeVisible(); + }); +}); +``` + +### Available Scripts + +```bash +npm run e2e # Run all E2E tests +npm run e2e:ui # Run E2E tests with UI +npm run e2e:serve # Start dev server and run tests +``` + +## ๐ŸŽจ Visual Regression Testing + +### Overview + +Visual regression testing ensures UI consistency across browsers and prevents unintended visual changes. + +### Screenshots Generated + +- **Full page screenshots** (mobile, tablet, desktop) +- **Component screenshots** (hero, logo wall, cards, etc.) +- **Interactive states** (hover, focus, loading, error) +- **Special modes** (dark mode, high contrast, reduced motion) + +### Baseline Screenshots + +``` +tests/e2e/visual-regression.spec.ts-snapshots/ +โ”œโ”€โ”€ homepage-full-chromium-darwin.png +โ”œโ”€โ”€ homepage-mobile-chromium-darwin.png +โ”œโ”€โ”€ hero-banner-chromium-darwin.png +โ”œโ”€โ”€ logo-wall-chromium-darwin.png +โ””โ”€โ”€ ... (92 total screenshots) +``` + +### Managing Visual Changes + +```bash +# Update baselines after intentional changes +npx playwright test tests/e2e/visual-regression.spec.ts --update-snapshots + +# Run visual regression tests +npx playwright test tests/e2e/visual-regression.spec.ts +``` + +### Cross-Browser Coverage + +- **Chromium** (Chrome/Edge) +- **Firefox** +- **WebKit** (Safari) +- **Mobile** (Mobile Chrome) + +## โšก Performance Testing + +### Framework + +- **Lighthouse CI**: Automated performance testing +- **Performance Budgets**: Defined thresholds + +### Configuration + +```json +// lighthouserc.json +{ + "ci": { + "collect": { + "url": ["http://localhost:3000"], + "startServerCommand": "npm run preview" + }, + "assert": { + "assertions": { + "categories:performance": ["warn", { "minScore": 0.9 }], + "categories:accessibility": ["error", { "minScore": 0.95 }] + } + } + } +} +``` + +### Performance Metrics + +- **Core Web Vitals**: LCP, FID, CLS +- **Performance Score**: Overall performance rating +- **Accessibility Score**: WCAG compliance +- **Best Practices**: Web development standards +- **SEO Score**: Search engine optimization + +### Available Scripts + +```bash +npm run lhci # Run Lighthouse CI +``` + +## ๐Ÿ“š Storybook Testing + +### Framework + +- **Storybook**: Component development environment +- **@storybook/test-runner**: Automated testing +- **@storybook/test**: Testing utilities + +### Configuration + +```javascript +// .storybook/preview.js +export const parameters = { + a11y: { element: "#storybook-root", manual: false }, + viewport: { defaultViewport: "responsive" }, + chromatic: { viewports: [360, 768, 1024, 1440] }, +}; +``` + +### Testing Features + +- **Accessibility Testing**: Automated WCAG compliance +- **Visual Testing**: Component screenshots +- **Interaction Testing**: User interactions +- **Responsive Testing**: Multiple viewports + +### Available Scripts + +```bash +npm run storybook # Start Storybook dev server +npm run test:sb # Run Storybook tests +npm run build-storybook # Build Storybook +``` + +## ๐Ÿ”„ CI/CD Pipeline + +### Gitea Actions Workflow + +Location: `.gitea/workflows/ci.yml` + +### Pipeline Jobs + +#### 1. Unit Tests + +- **Node.js versions**: 18, 20 +- **Coverage reporting**: Codecov integration +- **Parallel execution**: Matrix strategy + +#### 2. E2E Tests + +- **Browsers**: Chromium, Firefox, WebKit +- **Parallel execution**: Matrix strategy +- **Artifact upload**: Test results and reports + +#### 3. Visual Regression Tests + +- **Screenshot comparison**: Baseline vs current +- **Artifact upload**: Screenshot diffs +- **Cross-browser validation** + +#### 4. Performance Tests + +- **Lighthouse CI**: Performance budgets +- **Core Web Vitals**: Monitoring +- **Accessibility compliance** + +#### 5. Storybook Tests + +- **Component testing**: Automated tests +- **Accessibility validation**: WCAG compliance +- **Build verification**: Storybook compilation + +#### 6. Lint & Format + +- **ESLint**: Code quality +- **Prettier**: Code formatting +- **Type checking**: TypeScript validation + +#### 7. Build Verification + +- **Next.js build**: Application compilation +- **Storybook build**: Documentation compilation + +### Triggers + +```yaml +on: + push: + branches: [main, develop] + pull_request: + branches: [main, develop] +``` + +## ๐Ÿ›  Development Workflow + +### 1. Feature Development + +```bash +# Create feature branch +git checkout -b feature/new-component + +# Write tests first (TDD) +npm run test:watch + +# Implement feature +# Ensure tests pass + +# Run E2E tests +npm run e2e + +# Commit changes +git add . +git commit -m "feat: add new component with tests" +``` + +### 2. Manual Runner Management + +The Gitea Actions runner is managed manually to save resources and provide control over when CI runs. + +#### Start Runner (Before Creating PR) + +```bash +# Start the runner to execute CI jobs +./start-runner.sh +``` + +#### Check Runner Status + +```bash +# Check if runner is running and see recent logs +./status-runner.sh +``` + +#### Stop Runner (After PR Complete) + +```bash +# Stop the runner to free up resources +./stop-runner.sh +``` + +#### Complete PR Workflow + +```bash +# 1. Start runner +./start-runner.sh + +# 2. Create Pull Request +# Go to repository โ†’ New Pull Request + +# 3. Monitor CI progress +./status-runner.sh +# Or check Gitea Actions page + +# 4. Stop runner when done +./stop-runner.sh +``` + +### 2. Pull Request Process + +1. **Create PR** โ†’ CI pipeline starts automatically +2. **Review CI Results** โ†’ All 7 jobs must pass +3. **Check Coverage** โ†’ Ensure >85% coverage +4. **Review Visual Changes** โ†’ Check screenshot diffs +5. **Merge** โ†’ Only if all checks pass + +### 3. Visual Changes + +```bash +# Make visual changes +# Run visual regression tests +npm run e2e:serve +npx playwright test tests/e2e/visual-regression.spec.ts + +# If changes are intentional, update baselines +npx playwright test tests/e2e/visual-regression.spec.ts --update-snapshots +``` + +### 4. Performance Monitoring + +```bash +# Check performance before deploying +npm run lhci + +# Review performance budgets +# Update lighthouserc.json if needed +``` + +## ๐Ÿ“‹ Best Practices + +### 1. Test-Driven Development + +- Write tests before implementation +- Use descriptive test names +- Test edge cases and error scenarios +- Maintain high test coverage + +### 2. Component Testing + +```jsx +// Good: Test behavior, not implementation +test("shows error message when form is invalid", () => { + render(
); + fireEvent.click(screen.getByRole("button")); + expect(screen.getByText("Please fill all fields")).toBeInTheDocument(); +}); + +// Avoid: Testing implementation details +test("calls onSubmit with form data", () => { + const mockSubmit = vi.fn(); + render(); + // Implementation details... +}); +``` + +### 3. E2E Testing + +- Test user workflows, not technical details +- Use semantic selectors (role, text, label) +- Test accessibility features +- Include error scenarios + +### 4. Visual Regression + +- Update baselines only for intentional changes +- Review screenshot diffs carefully +- Test across multiple viewports +- Consider animation states + +### 5. Performance Testing + +- Set realistic performance budgets +- Monitor Core Web Vitals +- Test on different network conditions +- Regular performance audits + +## ๐Ÿ”ง Troubleshooting + +### Common Issues + +#### 1. Unit Tests Failing + +```bash +# Run tests locally +npm test + +# Check for: +# - Missing imports +# - Incorrect assertions +# - Component changes +# - Test environment issues +``` + +#### 2. E2E Tests Failing + +```bash +# Run locally first +npm run e2e:serve +npm run e2e + +# Common issues: +# - Selector changes +# - Component structure changes +# - Network issues +# - Browser compatibility +``` + +#### 3. Visual Regression Failing + +```bash +# Check if changes are intentional +npx playwright test tests/e2e/visual-regression.spec.ts + +# Update baselines if needed +npx playwright test tests/e2e/visual-regression.spec.ts --update-snapshots + +# Review screenshot diffs in CI artifacts +``` + +#### 4. Performance Tests Failing + +```bash +# Run locally +npm run lhci + +# Check performance budgets in lighthouserc.json +# Optimize slow components +# Review bundle size +``` + +#### 5. CI Pipeline Issues + +```bash +# Check Gitea Actions logs +# Verify workflow configuration +# Check for missing dependencies +# Review environment variables +``` + +### Debug Commands + +```bash +# Debug unit tests +npm run test:ui + +# Debug E2E tests +npm run e2e:ui + +# Debug with browser dev tools +npx playwright test --debug + +# Run specific test file +npx playwright test tests/e2e/homepage.spec.ts + +# Run tests in headed mode +npx playwright test --headed +``` + +## ๐Ÿ“Š Monitoring & Metrics + +### 1. Test Coverage + +- **Target**: >85% line coverage +- **Monitoring**: Codecov integration +- **Trends**: Track coverage over time +- **Reports**: Available in CI artifacts + +### 2. Performance Metrics + +- **Core Web Vitals**: LCP < 2.5s, FID < 100ms, CLS < 0.1 +- **Performance Score**: >90 +- **Accessibility Score**: >95 +- **Monitoring**: Lighthouse CI reports + +### 3. Visual Regression + +- **Baseline Screenshots**: 92 total +- **Cross-browser Coverage**: 4 browsers +- **Responsive Testing**: 4 viewports +- **Monitoring**: Screenshot diffs in CI + +### 4. E2E Test Results + +- **Total Tests**: 308 across 4 browsers +- **Success Rate**: Monitor test stability +- **Execution Time**: Track performance +- **Reports**: Available in CI artifacts + +### 5. CI Pipeline Health + +- **Job Success Rate**: Monitor pipeline stability +- **Execution Time**: Track build performance +- **Resource Usage**: Monitor CI costs +- **Failure Analysis**: Identify common issues + +## ๐Ÿ“š Additional Resources + +### Documentation + +- [Vitest Documentation](https://vitest.dev/) +- [Playwright Documentation](https://playwright.dev/) +- [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) +- [Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci) +- [Storybook Testing](https://storybook.js.org/docs/writing-tests/introduction) + +### Tools + +- [Codecov](https://codecov.io/) - Coverage reporting +- [Axe-core](https://github.com/dequelabs/axe-core) - Accessibility testing +- [MSW](https://mswjs.io/) - API mocking + +### Best Practices + +- [Testing Best Practices](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library) +- [E2E Testing Guide](https://playwright.dev/docs/best-practices) +- [Visual Regression Testing](https://storybook.js.org/docs/writing-tests/visual-testing) + +--- + +**Last Updated**: December 2024 +**Framework Version**: Next.js 15 + React 19 + Tailwind 4 + Storybook 9 diff --git a/docs/TESTING_QUICK_REFERENCE.md b/docs/TESTING_QUICK_REFERENCE.md new file mode 100644 index 0000000..c51f7cc --- /dev/null +++ b/docs/TESTING_QUICK_REFERENCE.md @@ -0,0 +1,275 @@ +# Testing Quick Reference + +## ๐Ÿš€ Essential Commands + +### Daily Development + +```bash +# Run all tests +npm test + +# Watch mode (during development) +npm run test:watch + +# E2E tests +npm run e2e + +# Performance check +npm run lhci +``` + +### Manual Runner Management + +```bash +# Start runner (before creating PR) +./start-runner.sh + +# Check runner status +./status-runner.sh + +# Stop runner (after PR complete) +./stop-runner.sh +``` + +### Visual Regression + +```bash +# Update baselines after intentional changes +npx playwright test tests/e2e/visual-regression.spec.ts --update-snapshots + +# Check for visual changes +npx playwright test tests/e2e/visual-regression.spec.ts +``` + +### Debugging + +```bash +# Debug unit tests +npm run test:ui + +# Debug E2E tests +npm run e2e:ui + +# Debug with browser +npx playwright test --debug +``` + +## ๐Ÿ“ Writing Tests + +### Unit Test Template + +```jsx +// tests/unit/Component.test.jsx +import { render, screen } from "@testing-library/react"; +import { describe, test, expect, afterEach } from "vitest"; +import { cleanup } from "@testing-library/react"; +import Component from "../../app/components/Component"; + +describe("Component", () => { + afterEach(() => cleanup()); + + test("renders correctly", () => { + render(); + expect(screen.getByRole("button")).toBeInTheDocument(); + }); +}); +``` + +### E2E Test Template + +```typescript +// tests/e2e/feature.spec.ts +import { test, expect } from "@playwright/test"; + +test.describe("Feature", () => { + test.beforeEach(async ({ page }) => { + await page.goto("/"); + }); + + test("should work correctly", async ({ page }) => { + await expect(page).toHaveTitle(/CommunityRule/); + await expect(page.locator("h1")).toBeVisible(); + }); +}); +``` + +## ๐Ÿ”ง Common Testing Patterns + +### Testing User Interactions + +```jsx +// Unit test +import userEvent from "@testing-library/user-event"; + +test("handles user input", async () => { + const user = userEvent.setup(); + render(); + + await user.type(screen.getByLabelText("Email"), "test@example.com"); + await user.click(screen.getByRole("button", { name: "Submit" })); + + expect(screen.getByText("Success")).toBeInTheDocument(); +}); +``` + +### Testing Async Operations + +```jsx +// Unit test +test("loads data", async () => { + render(); + + expect(screen.getByText("Loading...")).toBeInTheDocument(); + + await waitFor(() => { + expect(screen.getByText("Data loaded")).toBeInTheDocument(); + }); +}); +``` + +### Testing Accessibility + +```typescript +// E2E test +import { runA11y } from "./axe"; + +test("meets accessibility standards", async ({ page }) => { + await page.goto("/"); + const violations = await runA11y(page); + expect(violations).toEqual([]); +}); +``` + +## ๐ŸŽฏ Test Coverage Targets + +- **Lines**: 85% +- **Functions**: 85% +- **Statements**: 85% +- **Branches**: 80% + +## ๐Ÿšจ Common Issues & Solutions + +### Unit Tests + +```bash +# Issue: JSX not parsing in .js files +# Solution: Ensure vitest.config.js has proper esbuild config + +# Issue: Component not rendering +# Solution: Check imports and component exports + +# Issue: Test cleanup errors +# Solution: Add afterEach(cleanup()) to test suites +``` + +### E2E Tests + +```bash +# Issue: Element not found +# Solution: Use semantic selectors (role, text, label) + +# Issue: Test timeout +# Solution: Add proper waitFor or waitForLoadState + +# Issue: Multiple elements with same selector +# Solution: Use .first(), .nth(), or more specific selectors +``` + +### Visual Regression + +```bash +# Issue: Screenshots don't match +# Solution: Check if changes are intentional, then update baselines + +# Issue: Elements not visible +# Solution: Ensure elements are in viewport before screenshot +``` + +## ๐Ÿ“Š Performance Budgets + +### Lighthouse CI Targets + +- **Performance Score**: >90 +- **Accessibility Score**: >95 +- **Best Practices**: >90 +- **SEO Score**: >90 + +### Core Web Vitals + +- **LCP**: <2.5s +- **FID**: <100ms +- **CLS**: <0.1 + +## ๐Ÿ”„ CI/CD Pipeline Jobs + +1. **Unit Tests** (Node 18, 20) +2. **E2E Tests** (Chromium, Firefox, WebKit) +3. **Visual Regression Tests** +4. **Performance Tests** +5. **Storybook Tests** +6. **Lint & Format** +7. **Build Verification** + +## ๐Ÿ“ Test File Structure + +``` +tests/ +โ”œโ”€โ”€ unit/ # Component tests +โ”‚ โ”œโ”€โ”€ Button.test.jsx +โ”‚ โ”œโ”€โ”€ HeroBanner.test.jsx +โ”‚ โ””โ”€โ”€ ... +โ”œโ”€โ”€ integration/ # Integration tests +โ”‚ โ””โ”€โ”€ ContentLockup.integration.test.jsx +โ””โ”€โ”€ e2e/ # E2E tests + โ”œโ”€โ”€ homepage.spec.ts + โ”œโ”€โ”€ user-journeys.spec.ts + โ”œโ”€โ”€ edge-cases.spec.ts + โ””โ”€โ”€ visual-regression.spec.ts +``` + +## ๐ŸŽจ Visual Regression Screenshots + +### Generated Screenshots + +- Full page (mobile, tablet, desktop) +- Component sections (hero, logo wall, cards) +- Interactive states (hover, focus, loading) +- Special modes (dark, high contrast, reduced motion) + +### Managing Changes + +```bash +# Intentional changes +npx playwright test tests/e2e/visual-regression.spec.ts --update-snapshots + +# Review changes +npx playwright test tests/e2e/visual-regression.spec.ts +``` + +## ๐Ÿ“ˆ Monitoring + +### Test Metrics + +- **Unit Tests**: 124 tests +- **E2E Tests**: 308 tests (4 browsers) +- **Visual Screenshots**: 92 baselines +- **Coverage**: >85% target + +### CI Metrics + +- **Pipeline Jobs**: 7 parallel jobs +- **Execution Time**: Monitor build performance +- **Success Rate**: Track pipeline stability +- **Artifacts**: Test results and screenshots + +## ๐Ÿ”— Useful Links + +- [Full Testing Documentation](TESTING.md) +- [Vitest Docs](https://vitest.dev/) +- [Playwright Docs](https://playwright.dev/) +- [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) +- [Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci) + +--- + +**Quick Reference Version**: December 2024 diff --git a/docs/VISUAL_REGRESSION_SETUP.md b/docs/VISUAL_REGRESSION_SETUP.md new file mode 100644 index 0000000..fe31f89 --- /dev/null +++ b/docs/VISUAL_REGRESSION_SETUP.md @@ -0,0 +1,153 @@ +# Visual Regression Testing Setup + +This document explains how to set up and maintain visual regression tests for the CommunityRule platform. + +## Overview + +Visual regression tests capture screenshots of key UI components and compare them against baseline images to detect unintended visual changes. The tests are configured to work consistently across different environments (local development, CI/CD). + +## Configuration + +### Playwright Configuration + +The visual regression tests are configured in `playwright.config.ts` with the following key settings: + +- **OS-agnostic snapshots**: Uses `{testDir}/{testFileName}-snapshots/{arg}-{projectName}.png` template +- **Consistent rendering**: Fixed viewport (1280x800), device scale factor (1), and color scheme (light) +- **Tolerance settings**: Allows 1% pixel difference or 200 pixels maximum difference +- **Animation handling**: Disables animations during screenshot capture + +### CI Environment + +The CI workflow uses: + +- **Ubuntu Linux** with Playwright Docker image for consistent rendering +- **One-time snapshot seeding** on the main branch +- **Artifact packaging** to reduce file count and improve upload performance + +## Setting Up Snapshots + +### Option 1: CI Seeding (Recommended for New Projects) + +1. **Push to main branch**: The CI will automatically generate baseline snapshots +2. **Download artifacts**: Download the `visual-regression-results` artifact +3. **Extract snapshots**: Extract the `tests/e2e/visual-regression.spec.ts-snapshots/` folder +4. **Commit snapshots**: Add and commit the snapshot files to your repository +5. **Remove seeding step**: After snapshots are committed, remove the seeding step from CI + +### Option 2: Local Seeding with Docker (Recommended for Existing Projects) + +Use the provided script to generate snapshots in the same environment as CI: + +```bash +# Using the Docker container (ensures CI consistency) +npm run seed-snapshots + +# Or using local environment (may have slight differences) +npm run seed-snapshots:local +``` + +The Docker approach ensures: + +- Same fonts and rendering as CI +- Same file naming conventions +- Same performance characteristics + +## Running Visual Regression Tests + +### Local Development + +```bash +# Run all visual regression tests +npx playwright test tests/e2e/visual-regression.spec.ts + +# Run with UI for debugging +npx playwright test tests/e2e/visual-regression.spec.ts --ui + +# Update snapshots (use with caution) +PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts +``` + +### CI/CD + +Visual regression tests run automatically in the CI pipeline: + +- **Main branch**: Generates new snapshots if needed +- **Feature branches**: Compares against existing snapshots +- **Artifacts**: Uploads test results and snapshots for review + +## Troubleshooting + +### Common Issues + +1. **"Snapshot doesn't exist" errors** + + - **Cause**: Baseline snapshots haven't been generated + - **Solution**: Run snapshot seeding (see above) + +2. **Platform-specific failures** + + - **Cause**: Snapshots generated on different OS (macOS vs Linux) + - **Solution**: Use Docker container for local snapshot generation + +3. **Minor pixel differences** + + - **Cause**: Font rendering differences, anti-aliasing, etc. + - **Solution**: Check tolerance settings in `playwright.config.ts` + +4. **Animation-related failures** + - **Cause**: Animations not fully disabled + - **Solution**: Ensure `animations: "disabled"` is set in test configuration + +### Updating Snapshots + +When intentional UI changes are made: + +1. **Local update**: + + ```bash + PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts + ``` + +2. **Review changes**: Check the updated snapshots in `tests/e2e/visual-regression.spec.ts-snapshots/` + +3. **Commit changes**: Add and commit the updated snapshot files + +4. **Verify**: Run tests again to ensure they pass + +### Performance Considerations + +- **CI environment**: Tests run slower due to container overhead +- **Local development**: Faster execution with native browser +- **Artifact size**: Snapshots are compressed and packaged to reduce upload time + +## Best Practices + +1. **Consistent environment**: Always use the same environment for snapshot generation and testing +2. **Meaningful test names**: Use descriptive names for snapshot files +3. **Selective testing**: Test only critical UI components to maintain reasonable test duration +4. **Regular updates**: Update snapshots when making intentional UI changes +5. **Review failures**: Always review visual regression failures before updating snapshots + +## File Structure + +``` +tests/e2e/ +โ”œโ”€โ”€ visual-regression.spec.ts # Test definitions +โ””โ”€โ”€ visual-regression.spec.ts-snapshots/ # Baseline images + โ”œโ”€โ”€ homepage-full-chromium.png + โ”œโ”€โ”€ homepage-viewport-chromium.png + โ”œโ”€โ”€ hero-banner-chromium.png + โ””โ”€โ”€ ... +``` + +## Integration with Other Tests + +Visual regression tests complement: + +- **Unit tests**: Verify component logic +- **Integration tests**: Verify component interactions +- **E2E tests**: Verify user workflows +- **Accessibility tests**: Verify accessibility compliance + +Together, these tests provide comprehensive coverage of the application's functionality and appearance. diff --git a/gitea-runner.plist b/gitea-runner.plist new file mode 100644 index 0000000..9afa264 --- /dev/null +++ b/gitea-runner.plist @@ -0,0 +1,25 @@ + + + + + Label + com.gitea.act-runner + ProgramArguments + + /Users/Vinod/Documents/GitHub/community-rule/act_runner + daemon + --config + /Users/Vinod/Documents/GitHub/community-rule/config.yaml + + WorkingDirectory + /Users/Vinod/Documents/GitHub/community-rule + RunAtLoad + + KeepAlive + + StandardOutPath + /Users/Vinod/Documents/GitHub/community-rule/runner.log + StandardErrorPath + /Users/Vinod/Documents/GitHub/community-rule/runner-error.log + + diff --git a/lighthouserc.json b/lighthouserc.json new file mode 100644 index 0000000..bfcbe05 --- /dev/null +++ b/lighthouserc.json @@ -0,0 +1,78 @@ +{ + "ci": { + "collect": { + "startServerCommand": "npm run preview", + "url": ["http://localhost:3000/"], + "numberOfRuns": 3, + "settings": { + "preset": "desktop", + "throttling": { + "rttMs": 40, + "throughputKbps": 10240, + "cpuSlowdownMultiplier": 1, + "requestLatencyMs": 0, + "downloadThroughputKbps": 0, + "uploadThroughputKbps": 0 + } + } + }, + "assert": { + "assertions": { + "categories:performance": ["error", { "minScore": 0.9 }], + "categories:accessibility": ["warn", { "minScore": 0.95 }], + "categories:best-practices": ["warn", { "minScore": 0.9 }], + "categories:seo": ["warn", { "minScore": 0.9 }], + "first-contentful-paint": ["warn", { "maxNumericValue": 2000 }], + "largest-contentful-paint": ["warn", { "maxNumericValue": 2500 }], + "first-meaningful-paint": ["warn", { "maxNumericValue": 2000 }], + "speed-index": ["warn", { "maxNumericValue": 3000 }], + "interactive": ["warn", { "maxNumericValue": 3000 }], + "total-blocking-time": ["warn", { "maxNumericValue": 300 }], + "cumulative-layout-shift": ["warn", { "maxNumericValue": 0.1 }], + "max-potential-fid": ["warn", { "maxNumericValue": 130 }], + "server-response-time": ["warn", { "maxNumericValue": 600 }], + "render-blocking-resources": ["warn", { "maxLength": 0 }], + "unused-css-rules": ["warn", { "maxLength": 0 }], + "unused-javascript": ["warn", { "maxLength": 0 }], + "modern-image-formats": ["warn", { "maxLength": 0 }], + "uses-optimized-images": ["warn", { "maxLength": 0 }], + "uses-text-compression": ["warn", { "maxLength": 0 }], + "uses-responsive-images": ["warn", { "maxLength": 0 }], + "efficient-animated-content": ["warn", { "maxLength": 0 }], + "preload-lcp-image": ["warn", { "maxLength": 0 }], + "total-byte-weight": ["warn", { "maxNumericValue": 500000 }], + "uses-long-cache-ttl": ["warn", { "maxLength": 0 }], + "dom-size": ["warn", { "maxNumericValue": 1500 }], + "critical-request-chains": ["warn", { "maxLength": 0 }], + "user-timings": ["warn", { "maxLength": 0 }], + "bootup-time": ["warn", { "maxNumericValue": 1000 }], + "mainthread-work-breakdown": ["warn", { "maxLength": 0 }], + "font-display": ["warn", { "maxLength": 0 }], + "resource-summary": ["warn", { "maxLength": 0 }], + "third-party-summary": ["warn", { "maxLength": 0 }], + "largest-contentful-paint-element": ["warn", { "maxLength": 0 }], + "layout-shift-elements": ["warn", { "maxLength": 0 }], + "long-tasks": ["warn", { "maxLength": 0 }], + "non-composited-animations": ["warn", { "maxLength": 0 }], + "unsized-images": ["warn", { "maxLength": 0 }] + } + }, + "upload": { + "target": "temporary-public-storage", + "outputDir": "./lighthouse-results" + } + }, + "settings": { + "onlyCategories": ["performance", "accessibility", "best-practices", "seo"], + "skipAudits": ["uses-http2"], + "formFactor": "desktop", + "throttling": { + "rttMs": 40, + "throughputKbps": 10240, + "cpuSlowdownMultiplier": 1, + "requestLatencyMs": 0, + "downloadThroughputKbps": 0, + "uploadThroughputKbps": 0 + } + } +} diff --git a/package-lock.json b/package-lock.json index a572d6d..bec0a81 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,27 +14,48 @@ "react-dom": "^19.0.0" }, "devDependencies": { + "@axe-core/playwright": "^4.10.2", "@chromatic-com/storybook": "^4.1.0", "@eslint/eslintrc": "^3", + "@lhci/cli": "^0.15.1", + "@playwright/test": "^1.55.0", "@storybook/addon-a11y": "^9.1.2", + "@storybook/addon-actions": "^9.0.8", "@storybook/addon-docs": "^9.1.2", + "@storybook/addon-essentials": "^8.6.14", + "@storybook/addon-interactions": "^8.6.14", "@storybook/addon-onboarding": "^9.1.2", "@storybook/addon-styling-webpack": "^2.0.0", "@storybook/addon-viewport": "^9.0.8", "@storybook/addon-vitest": "^9.1.2", "@storybook/nextjs-vite": "^9.1.2", + "@storybook/test": "^8.6.14", + "@storybook/test-runner": "^0.23.0", "@svgr/webpack": "^8.1.0", "@tailwindcss/postcss": "^4.1.11", + "@testing-library/jest-dom": "^6.8.0", + "@testing-library/react": "^16.3.0", + "@testing-library/user-event": "^14.6.1", + "@types/react": "19.1.12", + "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/parser": "^8.41.0", + "@vitejs/plugin-react": "^5.0.2", "@vitest/browser": "^3.2.4", "@vitest/coverage-v8": "^3.2.4", "eslint": "^9", - "eslint-config-next": "15.2.4", + "eslint-config-next": "15.2.0", "eslint-plugin-storybook": "^9.1.2", + "jest-axe": "^10.0.0", + "jsdom": "^26.1.0", + "msw": "^2.10.5", "playwright": "^1.54.2", "postcss": "^8.5.6", + "start-server-and-test": "^2.0.13", "storybook": "^9.1.2", "tailwindcss": "^4.0.0", - "vitest": "^3.2.4" + "typescript": "^5.9.2", + "vitest": "^3.2.4", + "wait-on": "^8.0.4" } }, "node_modules/@adobe/css-tools": { @@ -71,6 +92,33 @@ "node": ">=6.0.0" } }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@axe-core/playwright": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.10.2.tgz", + "integrity": "sha512-6/b5BJjG6hDaRNtgzLIfKr5DfwyiLHO4+ByTLB0cJgWSM8Ll7KqtdblIS6bEkwSF642/Ex91vNqIl3GLXGlceg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "axe-core": "~4.10.3" + }, + "peerDependencies": { + "playwright-core": ">= 1.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -97,22 +145,22 @@ } }, "node_modules/@babel/core": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", - "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz", + "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", + "@babel/generator": "^7.28.3", "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.6", - "@babel/parser": "^7.28.0", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.3", + "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.0", - "@babel/types": "^7.28.0", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -327,15 +375,15 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" + "@babel/traverse": "^7.28.3" }, "engines": { "node": ">=6.9.0" @@ -463,9 +511,9 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", - "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.3.tgz", + "integrity": "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==", "dev": true, "license": "MIT", "dependencies": { @@ -589,6 +637,61 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", @@ -621,6 +724,32 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", @@ -637,6 +766,116 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", @@ -1397,6 +1636,38 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-pure-annotations": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", @@ -1850,6 +2121,37 @@ "node": ">=18" } }, + "node_modules/@bundled-es-modules/cookie": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cookie": "^0.7.2" + } + }, + "node_modules/@bundled-es-modules/statuses": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz", + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "dev": true, + "license": "ISC", + "dependencies": { + "statuses": "^2.0.1" + } + }, + "node_modules/@bundled-es-modules/tough-cookie": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz", + "integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@types/tough-cookie": "^4.0.5", + "tough-cookie": "^4.1.4" + } + }, "node_modules/@chromatic-com/storybook": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-4.1.0.tgz", @@ -1871,6 +2173,121 @@ "storybook": "^0.0.0-0 || ^9.0.0 || ^9.1.0-0 || ^9.2.0-0" } }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@emnapi/core": { "version": "1.4.5", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.5.tgz", @@ -2487,6 +2904,79 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.4.tgz", + "integrity": "sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/intl-localematcher": "0.6.1", + "decimal.js": "^10.4.3", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz", + "integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.2.tgz", + "integrity": "sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.4", + "@formatjs/icu-skeleton-parser": "1.8.14", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.8.14", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.14.tgz", + "integrity": "sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.4", + "tslib": "^2.8.0" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.1.tgz", + "integrity": "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -2914,6 +3404,134 @@ "url": "https://opencollective.com/libvips" } }, + "node_modules/@inquirer/confirm": { + "version": "5.1.16", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.16.tgz", + "integrity": "sha512-j1a5VstaK5KQy8Mu8cHmuQvN1Zc62TbLhjJxwHvKPPKEoowSF6h/0UdOpA9DNdWZ+9Inq73+puRq1df6OJ8Sag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.2.0", + "@inquirer/type": "^3.0.8" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.2.0.tgz", + "integrity": "sha512-NyDSjPqhSvpZEMZrLCYUquWNl+XC/moEcVFqS55IEYIYsY0a1cUCevSqk7ctOlnm/RaSBU5psFryNlxcmGrjaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.13", + "@inquirer/type": "^3.0.8", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@inquirer/core/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz", + "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz", + "integrity": "sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -2945,6 +3563,133 @@ "node": ">=18.0.0" } }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -2955,6 +3700,479 @@ "node": ">=8" } }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/core/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/create-cache-key-function": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-30.0.5.tgz", + "integrity": "sha512-W1kmkwPq/WTMQWgvbzWSCbXSqvjI6rkqBQCxuvYmd+g6o4b5gHP98ikfh/Ei0SKzHvWdI84TOXp0hRcbpr8Q0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/@jest/types": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.0.5.tgz", + "integrity": "sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/@sinclair/typebox": { + "version": "0.34.40", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.40.tgz", + "integrity": "sha512-gwBNIP8ZAYev/ORDWW0QvxdwPXwxBtLsdsJgSc7eDIRt8ubP+rxUBzPsrwnu16fgEF8Bx4lh/+mvQvJzcTM6Kw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern/node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/reporters/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/reporters/node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.6.1.tgz", @@ -3015,6 +4233,270 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@lhci/cli": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@lhci/cli/-/cli-0.15.1.tgz", + "integrity": "sha512-yhC0oXnXqGHYy1xl4D8YqaydMZ/khFAnXGY/o2m/J3PqPa/D0nj3V6TLoH02oVMFeEF2AQim7UbmdXMiXx2tOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@lhci/utils": "0.15.1", + "chrome-launcher": "^0.13.4", + "compression": "^1.7.4", + "debug": "^4.3.1", + "express": "^4.17.1", + "inquirer": "^6.3.1", + "isomorphic-fetch": "^3.0.0", + "lighthouse": "12.6.1", + "lighthouse-logger": "1.2.0", + "open": "^7.1.0", + "proxy-agent": "^6.4.0", + "tmp": "^0.1.0", + "uuid": "^8.3.1", + "yargs": "^15.4.1", + "yargs-parser": "^13.1.2" + }, + "bin": { + "lhci": "src/cli.js" + } + }, + "node_modules/@lhci/cli/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@lhci/cli/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/@lhci/cli/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@lhci/cli/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lhci/cli/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lhci/cli/node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@lhci/cli/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@lhci/cli/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lhci/cli/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@lhci/cli/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lhci/cli/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lhci/cli/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lhci/cli/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@lhci/cli/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@lhci/cli/node_modules/yargs/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@lhci/utils": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@lhci/utils/-/utils-0.15.1.tgz", + "integrity": "sha512-WclJnUQJeOMY271JSuaOjCv/aA0pgvuHZS29NFNdIeI14id8eiFsjith85EGKYhljgoQhJ2SiW4PsVfFiakNNw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.3.1", + "isomorphic-fetch": "^3.0.0", + "js-yaml": "^3.13.1", + "lighthouse": "12.6.1", + "tree-kill": "^1.2.1" + } + }, + "node_modules/@lhci/utils/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@lhci/utils/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@mdx-js/react": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", @@ -3033,6 +4515,24 @@ "react": ">=16" } }, + "node_modules/@mswjs/interceptors": { + "version": "0.39.6", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.39.6.tgz", + "integrity": "sha512-bndDP83naYYkfayr/qhBHMhk0YGwS1iv6vaEGcr0SQbO0IZtbOPqjKjds/WcG+bJA+1T5vCx6kprKOzn5Bg+Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "strict-event-emitter": "^0.5.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", @@ -3060,9 +4560,9 @@ "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { - "version": "15.2.4", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.2.4.tgz", - "integrity": "sha512-O8ScvKtnxkp8kL9TpJTTKnMqlkZnS+QxwoQnJwPGBxjBbzd6OVVPEJ5/pMNrktSyXQD/chEfzfFzYLM6JANOOQ==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.2.0.tgz", + "integrity": "sha512-jHFUG2OwmAuOASqq253RAEG/5BYcPHn27p1NoWZDCf4OdvdK0yRYWX92YKkL+Mk2s+GyJrmd/GATlL5b2IySpw==", "dev": true, "license": "MIT", "dependencies": { @@ -3245,6 +4745,42 @@ "node": ">=12.4.0" } }, + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@open-draft/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" + } + }, + "node_modules/@open-draft/until": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@paulirish/trace_engine": { + "version": "0.0.53", + "resolved": "https://registry.npmjs.org/@paulirish/trace_engine/-/trace_engine-0.0.53.tgz", + "integrity": "sha512-PUl/vlfo08Oj804VI5nDPeSk9vyslnBlVzDDwFt8SUVxY8+KdGMkra/vrXjEEHe8gb7+RqVTfOIlGw0nyrEelA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "legacy-javascript": "latest", + "third-party-web": "latest" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -3256,6 +4792,22 @@ "node": ">=14" } }, + "node_modules/@playwright/test": { + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.55.0.tgz", + "integrity": "sha512-04IXzPwHrW69XusN/SIdDdKZBzMfOT9UNT/YiJit/xpy2VuAoB8NHc8Aplb96zsWDddLnbkPL3TsmrS04ZU2xQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.55.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@polka/url": { "version": "1.0.0-next.29", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", @@ -3263,6 +4815,35 @@ "dev": true, "license": "MIT" }, + "node_modules/@puppeteer/browsers": { + "version": "2.10.8", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.8.tgz", + "integrity": "sha512-f02QYEnBDE0p8cteNoPYHHjbDuwyfbe4cCIVlNi8/MRicIxFW4w4CfgU0LNgWEID6s06P+hRJ1qjpBLMhPRCiQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.4.1", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.2", + "tar-fs": "^3.1.0", + "yargs": "^17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.34", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.34.tgz", + "integrity": "sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA==", + "dev": true, + "license": "MIT" + }, "node_modules/@rollup/pluginutils": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz", @@ -3580,6 +5161,142 @@ "dev": true, "license": "MIT" }, + "node_modules/@sentry-internal/tracing": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.120.4.tgz", + "integrity": "sha512-Fz5+4XCg3akeoFK+K7g+d7HqGMjmnLoY2eJlpONJmaeT9pXY7yfUyXKZMmMajdE2LxxKJgQ2YKvSCaGVamTjHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/core": "7.120.4", + "@sentry/types": "7.120.4", + "@sentry/utils": "7.120.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/core": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.120.4.tgz", + "integrity": "sha512-TXu3Q5kKiq8db9OXGkWyXUbIxMMuttB5vJ031yolOl5T/B69JRyAoKuojLBjRv1XX583gS1rSSoX8YXX7ATFGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/types": "7.120.4", + "@sentry/utils": "7.120.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/integrations": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.120.4.tgz", + "integrity": "sha512-kkBTLk053XlhDCg7OkBQTIMF4puqFibeRO3E3YiVc4PGLnocXMaVpOSCkMqAc1k1kZ09UgGi8DxfQhnFEjUkpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/core": "7.120.4", + "@sentry/types": "7.120.4", + "@sentry/utils": "7.120.4", + "localforage": "^1.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/node": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.120.4.tgz", + "integrity": "sha512-qq3wZAXXj2SRWhqErnGCSJKUhPSlZ+RGnCZjhfjHpP49KNpcd9YdPTIUsFMgeyjdh6Ew6aVCv23g1hTP0CHpYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry-internal/tracing": "7.120.4", + "@sentry/core": "7.120.4", + "@sentry/integrations": "7.120.4", + "@sentry/types": "7.120.4", + "@sentry/utils": "7.120.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/types": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.120.4.tgz", + "integrity": "sha512-cUq2hSSe6/qrU6oZsEP4InMI5VVdD86aypE+ENrQ6eZEVLTCYm1w6XhW1NvIu3UuWh7gZec4a9J7AFpYxki88Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/utils": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.120.4.tgz", + "integrity": "sha512-zCKpyDIWKHwtervNK2ZlaK8mMV7gVUijAgFeJStH+CU/imcdquizV3pFLlSQYRswG+Lbyd6CT/LGRh3IbtkCFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/types": "7.120.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, "node_modules/@storybook/addon-a11y": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-9.1.2.tgz", @@ -3598,6 +5315,55 @@ "storybook": "^9.1.2" } }, + "node_modules/@storybook/addon-actions": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-9.0.8.tgz", + "integrity": "sha512-LFePu7PPnWN0Il/uoUpmA5T0J0C7d6haJIbg0pXrjxW2MQVSYXE4S4LSUz8fOImltBDV3xAl6tLPYHFj6VcrOA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + } + }, + "node_modules/@storybook/addon-backgrounds": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.14.tgz", + "integrity": "sha512-l9xS8qWe5n4tvMwth09QxH2PmJbCctEvBAc1tjjRasAfrd69f7/uFK4WhwJAstzBTNgTc8VXI4w8ZR97i1sFbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "memoizerific": "^1.11.3", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-controls": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.14.tgz", + "integrity": "sha512-IiQpkNJdiRyA4Mq9mzjZlvQugL/aE7hNgVxBBGPiIZG6wb6Ht9hNnBYpap5ZXXFKV9p2qVI0FZK445ONmAa+Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "dequal": "^2.0.2", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, "node_modules/@storybook/addon-docs": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-9.1.2.tgz", @@ -3621,6 +5387,196 @@ "storybook": "^9.1.2" } }, + "node_modules/@storybook/addon-essentials": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.14.tgz", + "integrity": "sha512-5ZZSHNaW9mXMOFkoPyc3QkoNGdJHETZydI62/OASR0lmPlJ1065TNigEo5dJddmZNn0/3bkE8eKMAzLnO5eIdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/addon-actions": "8.6.14", + "@storybook/addon-backgrounds": "8.6.14", + "@storybook/addon-controls": "8.6.14", + "@storybook/addon-docs": "8.6.14", + "@storybook/addon-highlight": "8.6.14", + "@storybook/addon-measure": "8.6.14", + "@storybook/addon-outline": "8.6.14", + "@storybook/addon-toolbars": "8.6.14", + "@storybook/addon-viewport": "8.6.14", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-actions": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.14.tgz", + "integrity": "sha512-mDQxylxGGCQSK7tJPkD144J8jWh9IU9ziJMHfB84PKpI/V5ZgqMDnpr2bssTrUaGDqU5e1/z8KcRF+Melhs9pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@types/uuid": "^9.0.1", + "dequal": "^2.0.2", + "polished": "^4.2.2", + "uuid": "^9.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-docs": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.14.tgz", + "integrity": "sha512-Obpd0OhAF99JyU5pp5ci17YmpcQtMNgqW2pTXV8jAiiipWpwO++hNDeQmLmlSXB399XjtRDOcDVkoc7rc6JzdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mdx-js/react": "^3.0.0", + "@storybook/blocks": "8.6.14", + "@storybook/csf-plugin": "8.6.14", + "@storybook/react-dom-shim": "8.6.14", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-viewport": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.14.tgz", + "integrity": "sha512-gNzVQbMqRC+/4uQTPI2ZrWuRHGquTMZpdgB9DrD88VTEjNudP+J6r8myLfr2VvGksBbUMHkGHMXHuIhrBEnXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "memoizerific": "^1.11.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-essentials/node_modules/@storybook/csf-plugin": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.14.tgz", + "integrity": "sha512-dErtc9teAuN+eelN8FojzFE635xlq9cNGGGEu0WEmMUQ4iJ8pingvBO1N8X3scz4Ry7KnxX++NNf3J3gpxS8qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "unplugin": "^1.3.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-essentials/node_modules/@storybook/react-dom-shim": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.14.tgz", + "integrity": "sha512-0hixr3dOy3f3M+HBofp3jtMQMS+sqzjKNgl7Arfuj3fvjmyXOks/yGjDImySR4imPtEllvPZfhiQNlejheaInw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-essentials/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@storybook/addon-highlight": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.14.tgz", + "integrity": "sha512-4H19OJlapkofiE9tM6K/vsepf4ir9jMm9T+zw5L85blJZxhKZIbJ6FO0TCG9PDc4iPt3L6+aq5B0X29s9zicNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-interactions": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.6.14.tgz", + "integrity": "sha512-8VmElhm2XOjh22l/dO4UmXxNOolGhNiSpBcls2pqWSraVh4a670EyYBZsHpkXqfNHo2YgKyZN3C91+9zfH79qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/instrumenter": "8.6.14", + "@storybook/test": "8.6.14", + "polished": "^4.2.2", + "ts-dedent": "^2.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/addon-measure": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.14.tgz", + "integrity": "sha512-1Tlyb72NX8aAqm6I6OICsUuGOP6hgnXcuFlXucyhKomPa6j3Eu2vKu561t/f0oGtAK2nO93Z70kVaEh5X+vaGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "tiny-invariant": "^1.3.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, "node_modules/@storybook/addon-onboarding": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-9.1.2.tgz", @@ -3635,6 +5591,24 @@ "storybook": "^9.1.2" } }, + "node_modules/@storybook/addon-outline": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.14.tgz", + "integrity": "sha512-CW857JvN6OxGWElqjlzJO2S69DHf+xO3WsEfT5mT3ZtIjmsvRDukdWfDU9bIYUFyA2lFvYjncBGjbK+I91XR7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, "node_modules/@storybook/addon-styling-webpack": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@storybook/addon-styling-webpack/-/addon-styling-webpack-2.0.0.tgz", @@ -3646,6 +5620,20 @@ "webpack": "^5.0.0" } }, + "node_modules/@storybook/addon-toolbars": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.14.tgz", + "integrity": "sha512-W/wEXT8h3VyZTVfWK/84BAcjAxTdtRiAkT2KAN0nbSHxxB5KEM1MjKpKu2upyzzMa3EywITqbfy4dP6lpkVTwQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, "node_modules/@storybook/addon-viewport": { "version": "9.0.8", "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-9.0.8.tgz", @@ -3691,6 +5679,34 @@ } } }, + "node_modules/@storybook/blocks": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.14.tgz", + "integrity": "sha512-rBMHAfA39AGHgkrDze4RmsnQTMw1ND5fGWobr9pDcJdnDKWQWNRD7Nrlxj0gFlN3n4D9lEZhWGdFrCbku7FVAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/icons": "^1.2.12", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^8.6.14" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/@storybook/builder-vite": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-9.1.2.tgz", @@ -3748,6 +5764,62 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta" } }, + "node_modules/@storybook/instrumenter": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.14.tgz", + "integrity": "sha512-iG4MlWCcz1L7Yu8AwgsnfVAmMbvyRSk700Mfy2g4c8y5O+Cv1ejshE1LBBsCwHgkuqU0H4R0qu4g23+6UnUemQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@vitest/utils": "^2.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/instrumenter/node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@storybook/instrumenter/node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@storybook/instrumenter/node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@storybook/nextjs-vite": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/@storybook/nextjs-vite/-/nextjs-vite-9.1.2.tgz", @@ -3857,6 +5929,229 @@ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" } }, + "node_modules/@storybook/test": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.14.tgz", + "integrity": "sha512-GkPNBbbZmz+XRdrhMtkxPotCLOQ1BaGNp/gFZYdGDk2KmUWBKmvc5JxxOhtoXM2703IzNFlQHSSNnhrDZYuLlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/instrumenter": "8.6.14", + "@testing-library/dom": "10.4.0", + "@testing-library/jest-dom": "6.5.0", + "@testing-library/user-event": "14.5.2", + "@vitest/expect": "2.0.5", + "@vitest/spy": "2.0.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.6.14" + } + }, + "node_modules/@storybook/test-runner": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@storybook/test-runner/-/test-runner-0.23.0.tgz", + "integrity": "sha512-AVA6mSotfHAqsKjvWMNR7wcXIoCNQidU9P5GIGEdn+gArzkzTsLXZr6qNjH4XQRg8pSR+IUOuB1MMWZIHxhgoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5", + "@jest/types": "^29.6.3", + "@swc/core": "^1.5.22", + "@swc/jest": "^0.2.23", + "expect-playwright": "^0.8.0", + "jest": "^29.6.4", + "jest-circus": "^29.6.4", + "jest-environment-node": "^29.6.4", + "jest-junit": "^16.0.0", + "jest-playwright-preset": "^4.0.0", + "jest-runner": "^29.6.4", + "jest-serializer-html": "^7.1.0", + "jest-watch-typeahead": "^2.0.0", + "nyc": "^15.1.0", + "playwright": "^1.14.0" + }, + "bin": { + "test-storybook": "dist/test-storybook.js" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "storybook": "^0.0.0-0 || ^8.2.0 || ^9.0.0 || ^9.1.0-0" + } + }, + "node_modules/@storybook/test/node_modules/@testing-library/dom": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@storybook/test/node_modules/@testing-library/jest-dom": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz", + "integrity": "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@storybook/test/node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@storybook/test/node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@storybook/test/node_modules/@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@storybook/test/node_modules/@vitest/expect": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", + "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.0.5", + "@vitest/utils": "2.0.5", + "chai": "^5.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@storybook/test/node_modules/@vitest/pretty-format": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", + "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@storybook/test/node_modules/@vitest/spy": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", + "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@storybook/test/node_modules/@vitest/utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", + "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.0.5", + "estree-walker": "^3.0.3", + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@storybook/test/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/@storybook/test/node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@storybook/test/node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", @@ -4128,6 +6423,215 @@ "url": "https://github.com/sponsors/gregberge" } }, + "node_modules/@swc/core": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.5.tgz", + "integrity": "sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.24" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.13.5", + "@swc/core-darwin-x64": "1.13.5", + "@swc/core-linux-arm-gnueabihf": "1.13.5", + "@swc/core-linux-arm64-gnu": "1.13.5", + "@swc/core-linux-arm64-musl": "1.13.5", + "@swc/core-linux-x64-gnu": "1.13.5", + "@swc/core-linux-x64-musl": "1.13.5", + "@swc/core-win32-arm64-msvc": "1.13.5", + "@swc/core-win32-ia32-msvc": "1.13.5", + "@swc/core-win32-x64-msvc": "1.13.5" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.5.tgz", + "integrity": "sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.5.tgz", + "integrity": "sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.5.tgz", + "integrity": "sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.5.tgz", + "integrity": "sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.5.tgz", + "integrity": "sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.5.tgz", + "integrity": "sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.5.tgz", + "integrity": "sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.5.tgz", + "integrity": "sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.5.tgz", + "integrity": "sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.5.tgz", + "integrity": "sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, "node_modules/@swc/counter": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", @@ -4143,6 +6647,34 @@ "tslib": "^2.8.0" } }, + "node_modules/@swc/jest": { + "version": "0.2.39", + "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.39.tgz", + "integrity": "sha512-eyokjOwYd0Q8RnMHri+8/FS1HIrIUKK/sRrFp8c1dThUOfNeCWbLmBP1P5VsKdvmkd25JaH+OKYwEYiAYg9YAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/create-cache-key-function": "^30.0.0", + "@swc/counter": "^0.1.3", + "jsonc-parser": "^3.2.0" + }, + "engines": { + "npm": ">= 7.0.0" + }, + "peerDependencies": { + "@swc/core": "*" + } + }, + "node_modules/@swc/types": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.24.tgz", + "integrity": "sha512-tjTMh3V4vAORHtdTprLlfoMptu1WfTZG9Rsca6yOKyNYsRr+MUXutKmliB17orgSZk5DpnDxs8GUdd/qwYxOng==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, "node_modules/@tailwindcss/node": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", @@ -4440,9 +6972,9 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "6.6.4", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.4.tgz", - "integrity": "sha512-xDXgLjVunjHqczScfkCJ9iyjdNOVHvvCdqHSSxwM9L0l/wHkTRum67SDc020uAlCoqktJplgO2AAQeLP1wgqDQ==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.8.0.tgz", + "integrity": "sha512-WgXcWzVM6idy5JaftTVC8Vs83NKRmGJz4Hqs4oyOuO2J4r/y79vvKZsb+CaGyCSEbUPI6OsewfPd0G1A0/TUZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4450,7 +6982,6 @@ "aria-query": "^5.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", - "lodash": "^4.17.21", "picocolors": "^1.1.1", "redent": "^3.0.0" }, @@ -4467,6 +6998,34 @@ "dev": true, "license": "MIT" }, + "node_modules/@testing-library/react": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.0.tgz", + "integrity": "sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "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 + } + } + }, "node_modules/@testing-library/user-event": { "version": "14.6.1", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", @@ -4481,6 +7040,13 @@ "@testing-library/dom": ">=7.21.4" } }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true, + "license": "MIT" + }, "node_modules/@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", @@ -4564,6 +7130,13 @@ "@types/deep-eql": "*" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/deep-eql": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", @@ -4585,6 +7158,43 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -4606,6 +7216,26 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/node": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", + "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.10.0" + } + }, + "node_modules/@types/react": { + "version": "19.1.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz", + "integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, "node_modules/@types/resolve": { "version": "1.20.6", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", @@ -4613,18 +7243,84 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/statuses": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.6.tgz", + "integrity": "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/wait-on": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/@types/wait-on/-/wait-on-5.3.4.tgz", + "integrity": "sha512-EBsPjFMrFlMbbUFf9D1Fp+PAB2TwmUn7a3YtHyD9RLuTIk1jDd8SxXVAoez2Ciy+8Jsceo2MYEYZzJ/DvorOKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.39.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.1.tgz", - "integrity": "sha512-yYegZ5n3Yr6eOcqgj2nJH8cH/ZZgF+l0YIdKILSDjYFRjgYQMgv/lRjV5Z7Up04b9VYUondt8EPMqg7kTWgJ2g==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.41.0.tgz", + "integrity": "sha512-8fz6oa6wEKZrhXWro/S3n2eRJqlRcIa6SlDh59FXJ5Wp5XRZ8B9ixpJDcjadHq47hMx0u+HW6SNa6LjJQ6NLtw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.39.1", - "@typescript-eslint/type-utils": "8.39.1", - "@typescript-eslint/utils": "8.39.1", - "@typescript-eslint/visitor-keys": "8.39.1", + "@typescript-eslint/scope-manager": "8.41.0", + "@typescript-eslint/type-utils": "8.41.0", + "@typescript-eslint/utils": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -4638,7 +7334,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.39.1", + "@typescript-eslint/parser": "^8.41.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -4654,16 +7350,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.39.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.39.1.tgz", - "integrity": "sha512-pUXGCuHnnKw6PyYq93lLRiZm3vjuslIy7tus1lIQTYVK9bL8XBgJnCWm8a0KcTtHC84Yya1Q6rtll+duSMj0dg==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.41.0.tgz", + "integrity": "sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.39.1", - "@typescript-eslint/types": "8.39.1", - "@typescript-eslint/typescript-estree": "8.39.1", - "@typescript-eslint/visitor-keys": "8.39.1", + "@typescript-eslint/scope-manager": "8.41.0", + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/typescript-estree": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0", "debug": "^4.3.4" }, "engines": { @@ -4679,14 +7375,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.39.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.1.tgz", - "integrity": "sha512-8fZxek3ONTwBu9ptw5nCKqZOSkXshZB7uAxuFF0J/wTMkKydjXCzqqga7MlFMpHi9DoG4BadhmTkITBcg8Aybw==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.41.0.tgz", + "integrity": "sha512-b8V9SdGBQzQdjJ/IO3eDifGpDBJfvrNTp2QD9P2BeqWTGrRibgfgIlBSw6z3b6R7dPzg752tOs4u/7yCLxksSQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.39.1", - "@typescript-eslint/types": "^8.39.1", + "@typescript-eslint/tsconfig-utils": "^8.41.0", + "@typescript-eslint/types": "^8.41.0", "debug": "^4.3.4" }, "engines": { @@ -4701,14 +7397,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.39.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.1.tgz", - "integrity": "sha512-RkBKGBrjgskFGWuyUGz/EtD8AF/GW49S21J8dvMzpJitOF1slLEbbHnNEtAHtnDAnx8qDEdRrULRnWVx27wGBw==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.41.0.tgz", + "integrity": "sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.39.1", - "@typescript-eslint/visitor-keys": "8.39.1" + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4719,9 +7415,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.39.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.1.tgz", - "integrity": "sha512-ePUPGVtTMR8XMU2Hee8kD0Pu4NDE1CN9Q1sxGSGd/mbOtGZDM7pnhXNJnzW63zk/q+Z54zVzj44HtwXln5CvHA==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.41.0.tgz", + "integrity": "sha512-TDhxYFPUYRFxFhuU5hTIJk+auzM/wKvWgoNYOPcOf6i4ReYlOoYN8q1dV5kOTjNQNJgzWN3TUUQMtlLOcUgdUw==", "dev": true, "license": "MIT", "engines": { @@ -4736,15 +7432,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.39.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.39.1.tgz", - "integrity": "sha512-gu9/ahyatyAdQbKeHnhT4R+y3YLtqqHyvkfDxaBYk97EcbfChSJXyaJnIL3ygUv7OuZatePHmQvuH5ru0lnVeA==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.41.0.tgz", + "integrity": "sha512-63qt1h91vg3KsjVVonFJWjgSK7pZHSQFKH6uwqxAH9bBrsyRhO6ONoKyXxyVBzG1lJnFAJcKAcxLS54N1ee1OQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.39.1", - "@typescript-eslint/typescript-estree": "8.39.1", - "@typescript-eslint/utils": "8.39.1", + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/typescript-estree": "8.41.0", + "@typescript-eslint/utils": "8.41.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -4761,9 +7457,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.39.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.1.tgz", - "integrity": "sha512-7sPDKQQp+S11laqTrhHqeAbsCfMkwJMrV7oTDvtDds4mEofJYir414bYKUEb8YPUm9QL3U+8f6L6YExSoAGdQw==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.41.0.tgz", + "integrity": "sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==", "dev": true, "license": "MIT", "engines": { @@ -4775,16 +7471,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.39.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.1.tgz", - "integrity": "sha512-EKkpcPuIux48dddVDXyQBlKdeTPMmALqBUbEk38McWv0qVEZwOpVJBi7ugK5qVNgeuYjGNQxrrnoM/5+TI/BPw==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.41.0.tgz", + "integrity": "sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.39.1", - "@typescript-eslint/tsconfig-utils": "8.39.1", - "@typescript-eslint/types": "8.39.1", - "@typescript-eslint/visitor-keys": "8.39.1", + "@typescript-eslint/project-service": "8.41.0", + "@typescript-eslint/tsconfig-utils": "8.41.0", + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/visitor-keys": "8.41.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -4860,16 +7556,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.39.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.1.tgz", - "integrity": "sha512-VF5tZ2XnUSTuiqZFXCZfZs1cgkdd3O/sSYmdo2EpSyDlC86UM/8YytTmKnehOW3TGAlivqTDT6bS87B/GQ/jyg==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.41.0.tgz", + "integrity": "sha512-udbCVstxZ5jiPIXrdH+BZWnPatjlYwJuJkDA4Tbo3WyYLh8NvB+h/bKeSZHDOFKfphsZYJQqaFtLeXEqurQn1A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.39.1", - "@typescript-eslint/types": "8.39.1", - "@typescript-eslint/typescript-estree": "8.39.1" + "@typescript-eslint/scope-manager": "8.41.0", + "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/typescript-estree": "8.41.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4884,13 +7580,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.39.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.1.tgz", - "integrity": "sha512-W8FQi6kEh2e8zVhQ0eeRnxdvIoOkAp/CPAahcNio6nO9dsIwb9b34z90KOlheoyuVf6LSOEdjlkxSkapNEc+4A==", + "version": "8.41.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.41.0.tgz", + "integrity": "sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.39.1", + "@typescript-eslint/types": "8.41.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -5170,6 +7866,27 @@ "win32" ] }, + "node_modules/@vitejs/plugin-react": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.2.tgz", + "integrity": "sha512-tmyFgixPZCx2+e6VO9TNITWcCQl8+Nl/E8YbAyPVv85QCc7/A3JrdfG2A8gIzvVhWuzMOVrFW1aReaNxrI6tbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.3", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.34", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, "node_modules/@vitest/browser": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-3.2.4.tgz", @@ -5365,6 +8082,30 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", @@ -5388,6 +8129,30 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -5405,6 +8170,32 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -5431,6 +8222,60 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -5465,6 +8310,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT" + }, "node_modules/array-includes": { "version": "3.1.9", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", @@ -5677,6 +8529,13 @@ "node": ">= 0.4" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -5703,6 +8562,18 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -5713,6 +8584,132 @@ "node": ">= 0.4" } }, + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", @@ -5765,6 +8762,50 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -5772,6 +8813,93 @@ "dev": true, "license": "MIT" }, + "node_modules/bare-events": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.6.1.tgz", + "integrity": "sha512-AuTJkq9XmE6Vk0FJVNq5QxETrSA/vKHarWVBG5l/JbdCL1prJemiyJqUS0jrlXO0MftuPq4m3YVYhoNc5+aE/g==", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/bare-fs": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.2.1.tgz", + "integrity": "sha512-mELROzV0IhqilFgsl1gyp48pnZsaV9xhQapHLDsvn4d4ZTfbFhcghQezl7FTEDNBcGqLUnNI3lUlm6ecrLWdFA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-stream": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", + "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/better-opn": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", @@ -5785,6 +8913,68 @@ "node": ">=12.0.0" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -5849,6 +9039,33 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -5860,6 +9077,16 @@ "node": ">=10.16.0" } }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -5870,6 +9097,68 @@ "node": ">=8" } }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/caching-transform/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caching-transform/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/caching-transform/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/caching-transform/node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -5997,6 +9286,23 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -6007,6 +9313,16 @@ "node": ">= 16" } }, + "node_modules/check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/chownr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", @@ -6041,12 +9357,206 @@ } } }, + "node_modules/chrome-launcher": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.13.4.tgz", + "integrity": "sha512-nnzXiDbGKjDSK6t2I+35OAPBy5Pw/39bgkb/ZAFwMhwJbdYBp6aH+vW28ZgtjdU890Q7D+3wN/tB8N66q5Gi2A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^1.0.5", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0", + "mkdirp": "^0.5.3", + "rimraf": "^3.0.2" + } + }, + "node_modules/chrome-launcher/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/chrome-launcher/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/chromium-bidi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-8.0.0.tgz", + "integrity": "sha512-d1VmE0FD7lxZQHzcDUCKZSNRtRwISXDsdg4HjdTR5+Ll5nQ/vzU12JeNmupD6VWffrPSlrnGhEWlLESKH3VO+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "mitt": "^3.0.1", + "zod": "^3.24.1" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", "license": "MIT" }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -6092,6 +9602,19 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", @@ -6102,6 +9625,62 @@ "node": ">= 10" } }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -6109,6 +9688,93 @@ "dev": true, "license": "MIT" }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/configstore/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/configstore/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/configstore/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/configstore/node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -6116,6 +9782,23 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true, + "license": "MIT" + }, "node_modules/core-js-compat": { "version": "3.45.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.0.tgz", @@ -6157,6 +9840,28 @@ } } }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -6172,6 +9877,23 @@ "node": ">= 8" } }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/csp_evaluator": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/csp_evaluator/-/csp_evaluator-1.1.5.tgz", + "integrity": "sha512-EL/iN9etCTzw/fBnp0/uj0f5BOOGvZut2mzsiiBZ/FdT6gFQCKRO/tmcKOxn5drWZ2Ndm/xBb1SI4zwWbGtmIw==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/css-select": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", @@ -6259,6 +9981,27 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/cwd": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/cwd/-/cwd-0.10.0.tgz", + "integrity": "sha512-YGZxdTTL9lmLkCUTpg4j0zQ7IhRB5ZmqNBbGCl3Tg6MP/d5/6sY7L5mmTjzbc6JKgVZYiqTQTNhPFsbXNGlRaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-pkg": "^0.1.2", + "fs-exists-sync": "^0.1.0" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -6266,6 +10009,30 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/data-view-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", @@ -6338,6 +10105,38 @@ } } }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/dedent": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz", + "integrity": "sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, "node_modules/deep-eql": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", @@ -6365,6 +10164,32 @@ "node": ">=0.10.0" } }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-require-extensions/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -6411,6 +10236,54 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/degenerator/node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -6421,6 +10294,17 @@ "node": ">=6" } }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/detect-libc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", @@ -6431,6 +10315,43 @@ "node": ">=8" } }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1467305", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1467305.tgz", + "integrity": "sha512-LxwMLqBoPPGpMdRL4NkLFRNy3QLp6Uqa7GNp1v6JaBheop2QrB9Q7q0A/q/CYYP9sBfZdHOyszVx4gc9zyk7ow==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/diffable-html": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/diffable-html/-/diffable-html-4.1.0.tgz", + "integrity": "sha512-++kyNek+YBLH8cLXS+iTj/Hiy2s5qkRJEJ8kgu/WHbFrVY2vz9xPFUT+fii2zGF0m1CaojDlQJjkfrCt7YWM1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "htmlparser2": "^3.9.2" + } + }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -6521,6 +10442,19 @@ "tslib": "^2.0.3" } }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -6536,6 +10470,13 @@ "node": ">= 0.4" } }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true, + "license": "MIT" + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -6543,6 +10484,13 @@ "dev": true, "license": "MIT" }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, "node_modules/electron-to-chromium": { "version": "1.5.200", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.200.tgz", @@ -6550,6 +10498,19 @@ "dev": true, "license": "ISC" }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -6557,6 +10518,26 @@ "dev": true, "license": "MIT" }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.18.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", @@ -6571,6 +10552,33 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/enquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -6785,6 +10793,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "license": "MIT" + }, "node_modules/esbuild": { "version": "0.25.8", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", @@ -6850,6 +10865,13 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -6863,6 +10885,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, "node_modules/eslint": { "version": "9.33.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.33.0.tgz", @@ -6925,13 +10969,13 @@ } }, "node_modules/eslint-config-next": { - "version": "15.2.4", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.2.4.tgz", - "integrity": "sha512-v4gYjd4eYIme8qzaJItpR5MMBXJ0/YV07u7eb50kEnlEmX7yhOjdUdzz70v4fiINYRjLf8X8TbogF0k7wlz6sA==", + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.2.0.tgz", + "integrity": "sha512-LkG0KKpinAoNPk2HXSx0fImFb/hQ6RnhSxTkpJFTkQ0SmnzsbRsjjN95WC/mDY34nKOenpptYEVvfkCR/h+VjA==", "dev": true, "license": "MIT", "dependencies": { - "@next/eslint-plugin-next": "15.2.4", + "@next/eslint-plugin-next": "15.2.0", "@rushstack/eslint-patch": "^1.10.3", "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", @@ -7451,6 +11495,109 @@ "node": ">=0.10.0" } }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-homedir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect-playwright": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/expect-playwright/-/expect-playwright-0.8.0.tgz", + "integrity": "sha512-+kn8561vHAY+dt+0gMqqj1oY+g5xWrsuGMk4QGxotT2WS545nVqqjs37z6hrYfIuucwqthzwJfCJUEYqixyljg==", + "dev": true, + "license": "MIT" + }, "node_modules/expect-type": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", @@ -7461,6 +11608,175 @@ "node": ">=12.0.0" } }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor/node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -7468,6 +11784,13 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -7522,6 +11845,26 @@ "reusify": "^1.0.4" } }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/fdir": { "version": "6.4.6", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", @@ -7537,6 +11880,29 @@ } } }, + "node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -7573,6 +11939,148 @@ "node": ">=8" } }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/finalhandler/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-cache-dir/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/find-file-up": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/find-file-up/-/find-file-up-0.1.3.tgz", + "integrity": "sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fs-exists-sync": "^0.1.0", + "resolve-dir": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-pkg": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/find-pkg/-/find-pkg-0.1.2.tgz", + "integrity": "sha512-0rnQWcFwZr7eO0513HahrWafsc3CTFioEB7DRiEYCUM/70QXSY8f3mCST17HXLcPvEhzH/Ty/Bxd72ZZsr/yvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-file-up": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-process": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.11.tgz", + "integrity": "sha512-mAOh9gGk9WZ4ip5UjV0o6Vb4SrfnAmtsFNzkMRH9HQiFXVQnDyQFrSHTK5UoG6E+KV+s+cIznbtwpfN41l2nFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "~4.1.2", + "commander": "^12.1.0", + "loglevel": "^1.9.2" + }, + "bin": { + "find-process": "bin/find-process.js" + } + }, + "node_modules/find-process/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/find-up": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", @@ -7612,6 +12120,27 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -7645,6 +12174,88 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -7711,6 +12322,16 @@ "node": ">=6.9.0" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -7736,6 +12357,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -7750,6 +12381,19 @@ "node": ">= 0.4" } }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", @@ -7781,6 +12425,21 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -7841,6 +12500,49 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha512-JeXuCbvYzYXcwE6acL9V2bAOeSIGl4dD+iwLY9iUx2VBJJ80R18HCn+JCwHM9Oegdfya3lEkGCdaRkSyc10hDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^0.1.4", + "is-windows": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha512-gOPiyxcD9dJGCEArAhF4Hd0BAqvAe/JzERP7tYumE4yIkmIedPUVXcJFWbV3/p/ovIIvKjkrTk+f1UVkq7vvbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "homedir-polyfill": "^1.0.0", + "ini": "^1.3.4", + "is-windows": "^0.2.0", + "which": "^1.2.12" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -7905,6 +12607,16 @@ "dev": true, "license": "MIT" }, + "node_modules/graphql": { + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz", + "integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -7986,6 +12698,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -7999,6 +12738,39 @@ "node": ">= 0.4" } }, + "node_modules/headers-polyfill": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", + "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -8006,6 +12778,178 @@ "dev": true, "license": "MIT" }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/htmlparser2/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/htmlparser2/node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/htmlparser2/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/htmlparser2/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/htmlparser2/node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/htmlparser2/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-link-header": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/http-link-header/-/http-link-header-1.1.3.tgz", + "integrity": "sha512-3cZ0SRL8fb9MUlU3mKM61FcQvPfXx2dBrZW3Vbg5CXa8jFlK8OaEpePenLe1oEXQduhz8b0QjsqfS59QP4AJDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -8029,6 +12973,20 @@ "node": ">=16.x" } }, + "node_modules/image-ssim": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/image-ssim/-/image-ssim-0.2.0.tgz", + "integrity": "sha512-W7+sO6/yhxy83L0G7xR8YAc5Z5QFtYEXXRV6EaE8tuYBZJnA3gVgp3q7X7muhLZVodeb9UfvjSbwt9VJwjIYAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -8046,6 +13004,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -8066,6 +13044,249 @@ "node": ">=8" } }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/inquirer/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/inquirer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/inquirer/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/inquirer/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/string-width/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -8081,6 +13302,39 @@ "node": ">= 0.4" } }, + "node_modules/intl-messageformat": { + "version": "10.7.16", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.16.tgz", + "integrity": "sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@formatjs/ecma402-abstract": "2.3.4", + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/icu-messageformat-parser": "2.11.2", + "tslib": "^2.8.0" + } + }, + "node_modules/ip-address": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", + "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/is-array-buffer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", @@ -8285,6 +13539,16 @@ "node": ">=8" } }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/is-generator-function": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", @@ -8343,6 +13607,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "dev": true, + "license": "MIT" + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -8370,6 +13641,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -8418,6 +13706,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", @@ -8469,6 +13770,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true, + "license": "MIT" + }, "node_modules/is-weakmap": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", @@ -8515,6 +13823,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -8542,6 +13860,17 @@ "dev": true, "license": "ISC" }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -8552,6 +13881,54 @@ "node": ">=8" } }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "license": "ISC", + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", @@ -8630,6 +14007,1329 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-axe": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/jest-axe/-/jest-axe-10.0.0.tgz", + "integrity": "sha512-9QR0M7//o5UVRnEUUm68IsGapHrcKGakYy9dKWWMX79LmeUKguDI6DREyljC5I13j78OUmtKLF5My6ccffLFBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "axe-core": "4.10.2", + "chalk": "4.1.2", + "jest-matcher-utils": "29.2.2", + "lodash.merge": "4.6.2" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/jest-axe/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-axe/node_modules/axe-core": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-axe/node_modules/jest-matcher-utils": { + "version": "29.2.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.2.2.tgz", + "integrity": "sha512-4DkJ1sDPT+UX2MR7Y3od6KtvRi9Im1ZGLGgdLFLm4lPexbTaCgJW5NN3IOXlQHF7NSHY/VHhflQ+WoKtD/vyCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.2.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.2.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-axe/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-axe/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-changed-files/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-changed-files/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-circus/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-junit": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-16.0.0.tgz", + "integrity": "sha512-A94mmw6NfJab4Fg/BlvVOUXzXgF0XIH6EmTgJ5NDPp4xoKq0Kr7sErb+4Xs9nZvu58pJojz5RFGpqnZYJTrRfQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "mkdirp": "^1.0.4", + "strip-ansi": "^6.0.1", + "uuid": "^8.3.2", + "xml": "^1.0.1" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/jest-junit/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-junit/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-playwright-preset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jest-playwright-preset/-/jest-playwright-preset-4.0.0.tgz", + "integrity": "sha512-+dGZ1X2KqtwXaabVjTGxy0a3VzYfvYsWaRcuO8vMhyclHSOpGSI1+5cmlqzzCwQ3+fv0EjkTc7I5aV9lo08dYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect-playwright": "^0.8.0", + "jest-process-manager": "^0.4.0", + "nyc": "^15.1.0", + "playwright-core": ">=1.2.0", + "rimraf": "^3.0.2", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "jest": "^29.3.1", + "jest-circus": "^29.3.1", + "jest-environment-node": "^29.3.1", + "jest-runner": "^29.3.1" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-process-manager": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/jest-process-manager/-/jest-process-manager-0.4.0.tgz", + "integrity": "sha512-80Y6snDyb0p8GG83pDxGI/kQzwVTkCxc7ep5FPe/F6JYdvRDhwr6RzRmPSP7SEwuLhxo80lBS/NqOdUIbHIfhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/wait-on": "^5.2.0", + "chalk": "^4.1.0", + "cwd": "^0.10.0", + "exit": "^0.1.2", + "find-process": "^1.4.4", + "prompts": "^2.4.1", + "signal-exit": "^3.0.3", + "spawnd": "^5.0.0", + "tree-kill": "^1.2.2", + "wait-on": "^7.0.0" + } + }, + "node_modules/jest-process-manager/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/jest-process-manager/node_modules/wait-on": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz", + "integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "axios": "^1.6.1", + "joi": "^17.11.0", + "lodash": "^4.17.21", + "minimist": "^1.2.8", + "rxjs": "^7.8.1" + }, + "bin": { + "wait-on": "bin/wait-on" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-runner/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-runtime/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-serializer-html": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/jest-serializer-html/-/jest-serializer-html-7.1.0.tgz", + "integrity": "sha512-xYL2qC7kmoYHJo8MYqJkzrl/Fdlx+fat4U1AqYg+kafqwcKPiMkOcjWHPKhueuNEgr+uemhGc+jqXYiwCyRyLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "diffable-html": "^4.1.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-watch-typeahead": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-2.2.2.tgz", + "integrity": "sha512-+QgOFW4o5Xlgd6jGS5X37i08tuuXNW8X0CV9WNFi+3n8ExCIP+E1melYhvYLjv5fE6D0yyzk74vsSO8I6GqtvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^6.0.0", + "chalk": "^5.2.0", + "jest-regex-util": "^29.0.0", + "jest-watcher": "^29.0.0", + "slash": "^5.0.0", + "string-length": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "jest": "^27.0.0 || ^28.0.0 || ^29.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/chalk": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz", + "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/char-regex": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.2.tgz", + "integrity": "sha512-cbGOjAptfM2LVmWhwRFHEKTPkLwNddVmuqYZQt895yXwAsWsXObCG+YN4DGQ/JBtT4GP1a1lPPdio2z413LmTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/jest-watch-typeahead/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/jiti": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", @@ -8640,6 +15340,37 @@ "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/jpeg-js": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/js-library-detector": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/js-library-detector/-/js-library-detector-6.7.0.tgz", + "integrity": "sha512-c80Qupofp43y4cJ7+8TTDN/AsDwLi5oOm/plBrWI+iQt485vKXCco+yVmOwEgdo9VOdsYTuV0UlTeetVPTriXA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8660,6 +15391,73 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.5.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", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.1.1", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.1", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jsdom/node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -8714,6 +15512,13 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -8783,6 +15588,33 @@ "node": ">=0.10" } }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "> 0.8" + } + }, + "node_modules/legacy-javascript": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/legacy-javascript/-/legacy-javascript-0.0.1.tgz", + "integrity": "sha512-lPyntS4/aS7jpuvOlitZDFifBCb4W8L/3QU0PLbUTUj+zYah8rfVjYic88yG7ZKTxhS5h9iz7duT8oUXKszLhg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -8797,6 +15629,168 @@ "node": ">= 0.8.0" } }, + "node_modules/lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lighthouse": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/lighthouse/-/lighthouse-12.6.1.tgz", + "integrity": "sha512-85WDkjcXAVdlFem9Y6SSxqoKiz/89UsDZhLpeLJIsJ4LlHxw047XTZhlFJmjYCB7K5S1erSBAf5cYLcfyNbH3A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@paulirish/trace_engine": "0.0.53", + "@sentry/node": "^7.0.0", + "axe-core": "^4.10.3", + "chrome-launcher": "^1.2.0", + "configstore": "^5.0.1", + "csp_evaluator": "1.1.5", + "devtools-protocol": "0.0.1467305", + "enquirer": "^2.3.6", + "http-link-header": "^1.1.1", + "intl-messageformat": "^10.5.3", + "jpeg-js": "^0.4.4", + "js-library-detector": "^6.7.0", + "lighthouse-logger": "^2.0.1", + "lighthouse-stack-packs": "1.12.2", + "lodash-es": "^4.17.21", + "lookup-closest-locale": "6.2.0", + "metaviewport-parser": "0.3.0", + "open": "^8.4.0", + "parse-cache-control": "1.0.1", + "puppeteer-core": "^24.10.0", + "robots-parser": "^3.0.1", + "semver": "^5.3.0", + "speedline-core": "^1.4.3", + "third-party-web": "^0.26.6", + "tldts-icann": "^6.1.16", + "ws": "^7.0.0", + "yargs": "^17.3.1", + "yargs-parser": "^21.0.0" + }, + "bin": { + "chrome-debug": "core/scripts/manual-chrome-launcher.js", + "lighthouse": "cli/index.js", + "smokehouse": "cli/test/smokehouse/frontends/smokehouse-bin.js" + }, + "engines": { + "node": ">=18.20" + } + }, + "node_modules/lighthouse-logger": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.2.0.tgz", + "integrity": "sha512-wzUvdIeJZhRsG6gpZfmSCfysaxNEr43i+QT+Hie94wvHDKFLi4n7C2GqZ4sTC+PH5b5iktmXJvU87rWvhP3lHw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^2.6.8", + "marky": "^1.2.0" + } + }, + "node_modules/lighthouse-logger/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/lighthouse-logger/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/lighthouse-stack-packs": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/lighthouse-stack-packs/-/lighthouse-stack-packs-1.12.2.tgz", + "integrity": "sha512-Ug8feS/A+92TMTCK6yHYLwaFMuelK/hAKRMdldYkMNwv+d9PtWxjXEg6rwKtsUXTADajhdrhXyuNCJ5/sfmPFw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/lighthouse/node_modules/chrome-launcher": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.2.0.tgz", + "integrity": "sha512-JbuGuBNss258bvGil7FT4HKdC3SC2K7UAEUqiPy3ACS3Yxo3hAW6bvFpCu2HsIJLgTqxgEX6BkujvzZfLpUD0Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^2.0.1" + }, + "bin": { + "print-chrome-path": "bin/print-chrome-path.cjs" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/lighthouse/node_modules/lighthouse-logger": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-2.0.2.tgz", + "integrity": "sha512-vWl2+u5jgOQuZR55Z1WM0XDdrJT6mzMP8zHUct7xTlWhuQs+eV0g+QL0RQdFjT54zVmbhLCP8vIVpy1wGn/gCg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.4.1", + "marky": "^1.2.2" + } + }, + "node_modules/lighthouse/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/lighthouse/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/lighthouse/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/lightningcss": { "version": "1.30.1", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", @@ -9043,6 +16037,16 @@ "dev": true, "license": "MIT" }, + "node_modules/localforage": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "lie": "3.1.1" + } + }, "node_modules/locate-path": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", @@ -9066,6 +16070,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -9073,6 +16084,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -9080,6 +16098,27 @@ "dev": true, "license": "MIT" }, + "node_modules/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/lookup-closest-locale": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/lookup-closest-locale/-/lookup-closest-locale-6.2.0.tgz", + "integrity": "sha512-/c2kL+Vnp1jnV6K6RpDTHK3dgg0Tu2VVp+elEiJpjfS1UyY7AjOYHohRug6wT0OpoX2qFgNORndE9RqesfVxWQ==", + "dev": true, + "license": "MIT" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -9165,6 +16204,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/map-or-similar": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz", + "integrity": "sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==", + "dev": true, + "license": "MIT" + }, + "node_modules/map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", + "dev": true + }, + "node_modules/marky": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz", + "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -9182,6 +16251,43 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memoizerific": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", + "integrity": "sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==", + "dev": true, + "license": "MIT", + "dependencies": { + "map-or-similar": "^1.5.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -9192,6 +16298,23 @@ "node": ">= 8" } }, + "node_modules/metaviewport-parser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/metaviewport-parser/-/metaviewport-parser-0.3.0.tgz", + "integrity": "sha512-EoYJ8xfjQ6kpe9VbVHvZTZHiOl4HL1Z18CrZ+qahvLXT7ZO4YTC2JMyt5FaUp9JJp6J4Ybb/z7IsCXZt86/QkQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -9219,6 +16342,52 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -9275,6 +16444,13 @@ "node": ">= 18" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" + }, "node_modules/mkdirp": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", @@ -9315,6 +16491,74 @@ "dev": true, "license": "MIT" }, + "node_modules/msw": { + "version": "2.10.5", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.10.5.tgz", + "integrity": "sha512-0EsQCrCI1HbhpBWd89DvmxY6plmvrM96b0sCIztnvcNHQbXn5vqwm1KlXslo6u4wN9LFGLC1WFjjgljcQhe40A==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@bundled-es-modules/cookie": "^2.0.1", + "@bundled-es-modules/statuses": "^1.0.1", + "@bundled-es-modules/tough-cookie": "^0.1.6", + "@inquirer/confirm": "^5.0.0", + "@mswjs/interceptors": "^0.39.1", + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/until": "^2.1.0", + "@types/cookie": "^0.6.0", + "@types/statuses": "^2.0.4", + "graphql": "^16.8.1", + "headers-polyfill": "^4.0.2", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "path-to-regexp": "^6.3.0", + "picocolors": "^1.1.1", + "strict-event-emitter": "^0.5.1", + "type-fest": "^4.26.1", + "yargs": "^17.7.2" + }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mswjs" + }, + "peerDependencies": { + "typescript": ">= 4.8.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/msw/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -9356,6 +16600,26 @@ "dev": true, "license": "MIT" }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/next": { "version": "15.2.4", "resolved": "https://registry.npmjs.org/next/-/next-15.2.4.tgz", @@ -9449,6 +16713,72 @@ "tslib": "^2.0.3" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", @@ -9456,6 +16786,29 @@ "dev": true, "license": "MIT" }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -9469,6 +16822,369 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/nwsapi": { + "version": "2.2.21", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.21.tgz", + "integrity": "sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/nyc/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/nyc/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nyc/node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/nyc/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nyc/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -9592,6 +17308,55 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/open": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", @@ -9628,6 +17393,33 @@ "node": ">= 0.8.0" } }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outvariant": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", + "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", + "dev": true, + "license": "MIT" + }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", @@ -9678,6 +17470,79 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -9698,6 +17563,12 @@ "node": ">=6" } }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", + "dev": true + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -9717,6 +17588,52 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/path-exists": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", @@ -9727,6 +17644,16 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -9761,6 +17688,13 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT" + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -9788,6 +17722,26 @@ "node": ">= 14.16" } }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "dev": true, + "license": [ + "MIT", + "Apache2" + ], + "dependencies": { + "through": "~2.3" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -9807,14 +17761,103 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/playwright": { - "version": "1.54.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.54.2.tgz", - "integrity": "sha512-Hu/BMoA1NAdRUuulyvQC0pEqZ4vQbGfn8f7wPXcnqQmM+zct9UliKxsIkLNmz/ku7LElUNqmaiv1TG/aL5ACsw==", + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.55.0.tgz", + "integrity": "sha512-sdCWStblvV1YU909Xqx0DhOjPZE4/5lJsIS84IfN9dAZfcl/CIZ5O8l3o0j7hPMjDvqoTF8ZUcc+i/GL5erstA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.54.2" + "playwright-core": "1.55.0" }, "bin": { "playwright": "cli.js" @@ -9827,9 +17870,9 @@ } }, "node_modules/playwright-core": { - "version": "1.54.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.54.2.tgz", - "integrity": "sha512-n5r4HFbMmWsB4twG7tJLDN9gmBUeSPcsBZiWSE4DnYz9mJMAFqr2ID7+eGC9kpEnxExJ1epttwR59LEWCk8mtA==", + "version": "1.55.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.55.0.tgz", + "integrity": "sha512-GvZs4vU3U5ro2nZpeiwyb0zuFaqb9sUiAJuyrWpcGouD8y9/HLgGbNRjIph7zU9D3hnPaisMl9zG9CgFi/biIg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -9839,6 +17882,19 @@ "node": ">=18" } }, + "node_modules/polished": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", + "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.17.8" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -9916,6 +17972,29 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process-on-spawn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.1.0.tgz", + "integrity": "sha512-JOnOPQ/8TZgjs1JIH/m9ni7FfimjNa/PRx7y/Wb5qdItsnhO0jE4AT7fC0HjC28DUQWDr50dwSYZLdRMlqDq3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -9949,6 +18028,97 @@ "dev": true, "license": "MIT" }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ps-tree": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", + "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-stream": "=3.3.4" + }, + "bin": { + "ps-tree": "bin/ps-tree.js" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -9959,6 +18129,71 @@ "node": ">=6" } }, + "node_modules/puppeteer-core": { + "version": "24.17.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.17.1.tgz", + "integrity": "sha512-Msh/kf9k1XFN0wuKiT4/npMmMWOT7kPBEUw01gWvRoKOOoz3It9TEmWjnt4Gl4eO+p73VMrvR+wfa0dm9rfxjw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@puppeteer/browsers": "2.10.8", + "chromium-bidi": "8.0.0", + "debug": "^4.4.1", + "devtools-protocol": "0.0.1475386", + "typed-query-selector": "^2.12.0", + "ws": "^8.18.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer-core/node_modules/devtools-protocol": { + "version": "0.0.1475386", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1475386.tgz", + "integrity": "sha512-RQ809ykTfJ+dgj9bftdeL2vRVxASAuGU+I9LEx9Ij5TXU5HrgAQVmzi72VA+mkzscE12uzlRv5/tWWv9R9J1SA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true, + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9980,6 +18215,45 @@ ], "license": "MIT" }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react": { "version": "19.1.1", "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", @@ -10053,6 +18327,31 @@ "dev": true, "license": "MIT" }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/recast": { "version": "0.23.11", "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", @@ -10212,6 +18511,43 @@ "node": ">=6" } }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "license": "ISC", + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true, + "license": "ISC" + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -10233,6 +18569,43 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha512-QxMPqI6le2u0dCLyiGzgy92kjkkL6zO0XyvHzjdTNH3zM6e5Hz3BwG6+aEyNgiQ5Xz6PwTwgQEj3U50dByPKIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^1.2.2", + "global-modules": "^0.2.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -10253,6 +18626,60 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -10264,6 +18691,55 @@ "node": ">=0.10.0" } }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/robots-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/robots-parser/-/robots-parser-3.0.1.tgz", + "integrity": "sha512-s+pyvQeIKIZ0dx5iJiQk1tPLJAWln39+MI5jtM8wnyws+G5azk+dMnMX0qfbqNetKKNgcWWOdi0sfm+FbQbgdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/rollup": { "version": "4.46.2", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", @@ -10304,6 +18780,23 @@ "fsevents": "~2.3.2" } }, + "node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -10328,6 +18821,16 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-array-concat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", @@ -10348,6 +18851,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/safe-push-apply": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", @@ -10383,6 +18907,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/scheduler": { "version": "0.26.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", @@ -10402,6 +18946,91 @@ "node": ">=10" } }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -10451,6 +19080,13 @@ "node": ">= 0.4" } }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, "node_modules/sharp": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", @@ -10642,6 +19278,27 @@ "dev": true, "license": "MIT" }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, "node_modules/snake-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", @@ -10653,6 +19310,36 @@ "tslib": "^2.0.3" } }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -10672,6 +19359,147 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawn-wrap/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/spawn-wrap/node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spawn-wrap/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/spawn-wrap/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/spawn-wrap/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/spawnd": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/spawnd/-/spawnd-5.0.0.tgz", + "integrity": "sha512-28+AJr82moMVWolQvlAIv3JcYDkjkFTEmfDc503wxrF5l2rQ3dFz6DpbXp3kD4zmgGGldfM4xM4v1sFj/ZaIOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "exit": "^0.1.2", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "wait-port": "^0.2.9" + } + }, + "node_modules/spawnd/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/speedline-core": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/speedline-core/-/speedline-core-1.4.3.tgz", + "integrity": "sha512-DI7/OuAUD+GMpR6dmu8lliO2Wg5zfeh+/xsdyJZCzd8o5JgFUjCeLsBDuZjIQJdwXS3J0L/uZYrELKYqx+PXog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "image-ssim": "^0.2.0", + "jpeg-js": "^0.4.1" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/stable-hash": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", @@ -10679,6 +19507,29 @@ "dev": true, "license": "MIT" }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -10686,6 +19537,41 @@ "dev": true, "license": "MIT" }, + "node_modules/start-server-and-test": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.0.13.tgz", + "integrity": "sha512-G42GCIUjBv/nDoK+QsO+nBdX2Cg3DSAKhSic2DN0GLlK4Q+63TkOeN1cV9PHZKnVOzDKGNVZGCREjpvAIAOdiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "arg": "^5.0.2", + "bluebird": "3.7.2", + "check-more-types": "2.24.0", + "debug": "4.4.1", + "execa": "5.1.1", + "lazy-ass": "1.6.0", + "ps-tree": "1.2.0", + "wait-on": "8.0.4" + }, + "bin": { + "server-test": "src/bin/start.js", + "start-server-and-test": "src/bin/start.js", + "start-test": "src/bin/start.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/std-env": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", @@ -10743,6 +19629,16 @@ } } }, + "node_modules/stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1" + } + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -10751,6 +19647,64 @@ "node": ">=10.0.0" } }, + "node_modules/streamx": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz", + "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/strict-event-emitter": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -10971,6 +19925,16 @@ "node": ">=4" } }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/strip-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", @@ -11102,6 +20066,13 @@ "url": "https://opencollective.com/svgo" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, "node_modules/tailwindcss": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", @@ -11137,6 +20108,33 @@ "node": ">=18" } }, + "node_modules/tar-fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", + "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/test-exclude": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", @@ -11178,6 +20176,30 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/third-party-web": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/third-party-web/-/third-party-web-0.26.7.tgz", + "integrity": "sha512-buUzX4sXC4efFX6xg2bw6/eZsCUh8qQwSavC4D9HpONMFlRbcHhD8Je5qwYdCpViR6q0qla2wPP+t91a2vgolg==", + "dev": true, + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, "node_modules/tiny-invariant": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", @@ -11246,6 +20268,92 @@ "node": ">=14.0.0" } }, + "node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.86" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tldts-icann": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-icann/-/tldts-icann-6.1.86.tgz", + "integrity": "sha512-NFxmRT2lAEMcCOBgeZ0NuM0zsK/xgmNajnY6n4S1mwAKocft2s2ise1O3nQxrH3c+uY6hgHUV9GGNVp7tUE4Sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.86" + } + }, + "node_modules/tmp": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", + "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tmp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tmp/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -11259,6 +20367,16 @@ "node": ">=8.0" } }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, "node_modules/totalist": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", @@ -11269,6 +20387,55 @@ "node": ">=6" } }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -11347,6 +20514,43 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typed-array-buffer": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", @@ -11425,6 +20629,37 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typed-query-selector": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", + "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -11444,6 +20679,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "dev": true, + "license": "MIT" + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", @@ -11501,6 +20743,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -11511,6 +20766,16 @@ "node": ">= 10.0.0" } }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/unplugin": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz", @@ -11601,6 +20866,69 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/vite": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.1.tgz", @@ -11827,6 +21155,162 @@ } } }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/wait-on": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.4.tgz", + "integrity": "sha512-8f9LugAGo4PSc0aLbpKVCVtzayd36sSCp4WLpVngkYq6PK87H79zt77/tlCU6eKCLqR46iFvcl0PU5f+DmtkwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "axios": "^1.11.0", + "joi": "^17.13.3", + "lodash": "^4.17.21", + "minimist": "^1.2.8", + "rxjs": "^7.8.2" + }, + "bin": { + "wait-on": "bin/wait-on" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/wait-port": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/wait-port/-/wait-port-0.2.14.tgz", + "integrity": "sha512-kIzjWcr6ykl7WFbZd0TMae8xovwqcqbx6FM9l+7agOgUByhzdjfzZBPK2CPufldTOMxbUivss//Sh9MFawmPRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "commander": "^3.0.2", + "debug": "^4.1.1" + }, + "bin": { + "wait-port": "bin/wait-port.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wait-port/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wait-port/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wait-port/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/wait-port/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/wait-port/node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true, + "license": "MIT" + }, + "node_modules/wait-port/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/wait-port/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/wait-port/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, "node_modules/webpack-virtual-modules": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", @@ -11834,6 +21318,50 @@ "dev": true, "license": "MIT" }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -11917,6 +21445,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true, + "license": "ISC" + }, "node_modules/which-typed-array": { "version": "1.1.19", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", @@ -12051,6 +21586,34 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/ws": { "version": "8.18.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", @@ -12073,6 +21636,50 @@ } } }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", + "dev": true, + "license": "MIT" + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", @@ -12083,6 +21690,102 @@ "node": ">=18" } }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs-parser/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yocto-queue": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", @@ -12095,6 +21798,29 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 76a0703..1c7fc2d 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,31 @@ "lint": "next lint", "postinstall": "npm rebuild lightningcss", "storybook": "storybook dev -p 6006", - "storybook:local": "cp .storybook/main.local.js .storybook/main.js && cp .storybook/preview.local.js .storybook/preview.js && storybook dev -p 6006", - "storybook:restore": "cp .storybook/main.github.js .storybook/main.js && cp .storybook/preview.github.js .storybook/preview.js", - "build-storybook": "storybook build" + "storybook:local": "storybook dev -p 6006", + "storybook:github": "STORYBOOK_BASE_PATH=true storybook dev -p 6006", + "storybook:build": "storybook build", + "storybook:build:github": "STORYBOOK_BASE_PATH=true storybook build", + "build-storybook": "storybook build", + "test": "vitest run --coverage", + "test:watch": "vitest", + "test:ui": "vitest --ui", + "test:sb": "storybook dev -p 6006 & wait-on http://localhost:6006 && test-storybook", + "e2e": "playwright test", + "e2e:ui": "playwright test --ui", + "e2e:performance": "playwright test tests/e2e/performance.spec.ts", + "lhci": "lhci autorun", + "lhci:mobile": "lhci autorun --config=.lighthouserc.json --settings.preset=mobile", + "lhci:desktop": "lhci autorun --config=.lighthouserc.json --settings.preset=desktop", + "performance:budget": "lhci autorun --budgetPath=performance-budgets.json", + "performance:monitor": "node scripts/performance-monitor.js", + "test:lhci": "node scripts/test-lhci.js", + "preview": "next build && next start -p 3000", + "e2e:serve": "start-server-and-test preview http://localhost:3000 e2e", + "seed-snapshots": "./scripts/seed-snapshots.sh", + "seed-snapshots:local": "PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --project=chromium", + "visual:test": "npx playwright test tests/e2e/visual-regression.spec.ts", + "visual:update": "PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts", + "visual:ui": "npx playwright test tests/e2e/visual-regression.spec.ts --ui" }, "dependencies": { "next": "15.2.4", @@ -19,26 +41,47 @@ "react-dom": "^19.0.0" }, "devDependencies": { + "@axe-core/playwright": "^4.10.2", "@chromatic-com/storybook": "^4.1.0", "@eslint/eslintrc": "^3", + "@lhci/cli": "^0.15.1", + "@playwright/test": "^1.55.0", "@storybook/addon-a11y": "^9.1.2", + "@storybook/addon-actions": "^9.0.8", "@storybook/addon-docs": "^9.1.2", + "@storybook/addon-essentials": "^8.6.14", + "@storybook/addon-interactions": "^8.6.14", "@storybook/addon-onboarding": "^9.1.2", "@storybook/addon-styling-webpack": "^2.0.0", "@storybook/addon-viewport": "^9.0.8", "@storybook/addon-vitest": "^9.1.2", "@storybook/nextjs-vite": "^9.1.2", + "@storybook/test": "^8.6.14", + "@storybook/test-runner": "^0.23.0", "@svgr/webpack": "^8.1.0", "@tailwindcss/postcss": "^4.1.11", + "@testing-library/jest-dom": "^6.8.0", + "@testing-library/react": "^16.3.0", + "@testing-library/user-event": "^14.6.1", + "@types/react": "19.1.12", + "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/parser": "^8.41.0", + "@vitejs/plugin-react": "^5.0.2", "@vitest/browser": "^3.2.4", "@vitest/coverage-v8": "^3.2.4", "eslint": "^9", "eslint-config-next": "15.2.0", "eslint-plugin-storybook": "^9.1.2", + "jest-axe": "^10.0.0", + "jsdom": "^26.1.0", + "msw": "^2.10.5", "playwright": "^1.54.2", "postcss": "^8.5.6", + "start-server-and-test": "^2.0.13", "storybook": "^9.1.2", "tailwindcss": "^4.0.0", - "vitest": "^3.2.4" + "typescript": "^5.9.2", + "vitest": "^3.2.4", + "wait-on": "^8.0.4" } } diff --git a/performance-budgets.json b/performance-budgets.json new file mode 100644 index 0000000..b545e77 --- /dev/null +++ b/performance-budgets.json @@ -0,0 +1,186 @@ +{ + "performance": { + "budgets": [ + { + "path": "/*", + "timings": [ + { + "metric": "first-contentful-paint", + "budget": 2000 + }, + { + "metric": "largest-contentful-paint", + "budget": 2500 + }, + { + "metric": "first-meaningful-paint", + "budget": 2000 + }, + { + "metric": "speed-index", + "budget": 3000 + }, + { + "metric": "interactive", + "budget": 3000 + }, + { + "metric": "total-blocking-time", + "budget": 300 + }, + { + "metric": "cumulative-layout-shift", + "budget": 0.1 + }, + { + "metric": "max-potential-fid", + "budget": 130 + } + ], + "resourceSizes": [ + { + "resourceType": "script", + "budget": 300 + }, + { + "resourceType": "total", + "budget": 500 + }, + { + "resourceType": "image", + "budget": 100 + }, + { + "resourceType": "stylesheet", + "budget": 50 + }, + { + "resourceType": "font", + "budget": 50 + } + ], + "resourceCounts": [ + { + "resourceType": "script", + "budget": 10 + }, + { + "resourceType": "total", + "budget": 50 + }, + { + "resourceType": "image", + "budget": 20 + }, + { + "resourceType": "stylesheet", + "budget": 5 + }, + { + "resourceType": "font", + "budget": 5 + } + ] + } + ] + }, + "timing": { + "budgets": [ + { + "path": "/*", + "timings": [ + { + "metric": "first-contentful-paint", + "budget": 2000 + }, + { + "metric": "largest-contentful-paint", + "budget": 2500 + }, + { + "metric": "first-meaningful-paint", + "budget": 2000 + }, + { + "metric": "speed-index", + "budget": 3000 + }, + { + "metric": "interactive", + "budget": 3000 + }, + { + "metric": "total-blocking-time", + "budget": 300 + }, + { + "metric": "cumulative-layout-shift", + "budget": 0.1 + }, + { + "metric": "max-potential-fid", + "budget": 130 + } + ] + } + ] + }, + "resourceSizes": { + "budgets": [ + { + "path": "/*", + "resourceSizes": [ + { + "resourceType": "script", + "budget": 300 + }, + { + "resourceType": "total", + "budget": 500 + }, + { + "resourceType": "image", + "budget": 100 + }, + { + "resourceType": "stylesheet", + "budget": 50 + }, + { + "resourceType": "font", + "budget": 50 + } + ] + } + ] + }, + "resourceCounts": { + "budgets": [ + { + "path": "/*", + "resourceCounts": [ + { + "resourceType": "script", + "budget": 10 + }, + { + "resourceType": "total", + "budget": 50 + }, + { + "resourceType": "image", + "budget": 20 + }, + { + "resourceType": "stylesheet", + "budget": 5 + }, + { + "resourceType": "font", + "budget": 5 + } + ] + } + ] + } +} diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..3eb31e6 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,41 @@ +import { defineConfig, devices } from "@playwright/test"; + +export default defineConfig({ + testDir: "tests/e2e", + timeout: 60_000, + expect: { + timeout: 10_000, + toHaveScreenshot: { + animations: "disabled", + maxDiffPixelRatio: 0.01, // 1% pixels may differ + maxDiffPixels: 200, // or an absolute pixel count + }, + }, + fullyParallel: true, + retries: process.env.CI ? 2 : 0, + reporter: [["list"], ["html", { open: "never" }]], + use: { + baseURL: "http://localhost:3000", + trace: "on-first-retry", + screenshot: "only-on-failure", + video: "retain-on-failure", + colorScheme: "light", // Ensure consistent color scheme + viewport: { width: 1280, height: 800 }, // Consistent viewport + deviceScaleFactor: 1, // Consistent device scale + }, + webServer: { + command: "npm run dev", + url: "http://localhost:3000", + reuseExistingServer: true, + timeout: 120_000, + }, + // OS-agnostic snapshot path template (removes platform-specific suffixes) + snapshotPathTemplate: + "{testDir}/{testFileName}-snapshots/{arg}-{projectName}.png", + projects: [ + { name: "chromium", use: { ...devices["Desktop Chrome"] } }, + { name: "firefox", use: { ...devices["Desktop Firefox"] } }, + { name: "webkit", use: { ...devices["Desktop Safari"] } }, + { name: "mobile", use: { ...devices["iPhone 13"] } }, + ], +}); diff --git a/runner-config.yaml b/runner-config.yaml new file mode 100644 index 0000000..90d11af --- /dev/null +++ b/runner-config.yaml @@ -0,0 +1,10 @@ +log: + level: info + +runner: + capacity: 2 + +runners: + - name: community-rule-runner + labels: + - "ubuntu-latest:docker://mcr.microsoft.com/playwright:v1.54.2-jammy" diff --git a/runner-error.log b/runner-error.log new file mode 100644 index 0000000..b28a62d --- /dev/null +++ b/runner-error.log @@ -0,0 +1,16 @@ +time="2025-08-29T08:17:49-06:00" level=info msg="Starting runner daemon" +time="2025-08-29T08:17:50-06:00" level=info msg="runner: community-rule-runner-1, with version: v0.2.6, with labels: [macos-latest self-hosted], declare successfully" +time="2025-08-29T08:17:50-06:00" level=info msg="task 12 repo is CommunityRule/community-rule https://github.com https://git.medlab.host" +time="2025-08-29T08:17:52-06:00" level=info msg="task 13 repo is CommunityRule/community-rule https://github.com https://git.medlab.host" +time="2025-08-29T08:17:52-06:00" level=info msg="Parallel tasks (0) below minimum, setting to 1" +time="2025-08-29T08:17:54-06:00" level=info msg="task 14 repo is CommunityRule/community-rule https://github.com https://git.medlab.host" +time="2025-08-29T08:17:54-06:00" level=info msg="Parallel tasks (0) below minimum, setting to 1" +time="2025-08-29T08:17:55-06:00" level=info msg="Parallel tasks (0) below minimum, setting to 1" +time="2025-08-29T08:17:56-06:00" level=info msg="task 15 repo is CommunityRule/community-rule https://github.com https://git.medlab.host" +time="2025-08-29T08:17:57-06:00" level=info msg="Parallel tasks (0) below minimum, setting to 1" +time="2025-08-29T08:17:58-06:00" level=info msg="task 16 repo is CommunityRule/community-rule https://github.com https://git.medlab.host" +time="2025-08-29T08:17:58-06:00" level=info msg="Parallel tasks (0) below minimum, setting to 1" +time="2025-08-29T08:17:58-06:00" level=info msg="Starting runner daemon" +time="2025-08-29T08:17:59-06:00" level=info msg="runner: community-rule-runner-1, with version: v0.2.6, with labels: [macos-latest self-hosted], declare successfully" +time="2025-08-29T08:17:59-06:00" level=info msg="task 17 repo is CommunityRule/community-rule https://github.com https://git.medlab.host" +time="2025-08-29T08:18:01-06:00" level=info msg="Parallel tasks (0) below minimum, setting to 1" diff --git a/runner.log b/runner.log new file mode 100644 index 0000000..97b7d88 --- /dev/null +++ b/runner.log @@ -0,0 +1,675 @@ +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression 'success()' +[CI Pipeline/e2e (webkit)] [DEBUG] expression 'success()' evaluated to 'true' +[CI Pipeline/e2e (webkit)] โ˜ git clone 'https://github.com/actions/checkout' # ref=v4 +[CI Pipeline/e2e (webkit)] [DEBUG] cloning https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Unable to pull refs/heads/v4: worktree contains unstaged changes +[CI Pipeline/e2e (webkit)] [DEBUG] Cloned https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Checked out v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Read action &{Checkout Checkout a Git repository at a particular version map[clean:{Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching false true} fetch-depth:{Number of commits to fetch. 0 indicates all history for all branches and tags. false 1} fetch-tags:{Whether to fetch tags, even if fetch-depth > 0. false false} filter:{Partially clone against a given filter. Overrides sparse-checkout if set. + false } github-server-url:{The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com false } lfs:{Whether to download Git-LFS files false false} path:{Relative path under $GITHUB_WORKSPACE to place the repository false } persist-credentials:{Whether to configure the token or SSH key with the local git config false true} ref:{The branch, tag or SHA to checkout. When checking out the repository that triggered a workflow, this defaults to the reference or SHA for that event. Otherwise, uses the default branch. + false } repository:{Repository name with owner. For example, actions/checkout false ${{ github.repository }}} set-safe-directory:{Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory ` false true} show-progress:{Whether to show progress status output when fetching. false true} sparse-checkout:{Do a sparse checkout on given patterns. Each pattern should be separated with new lines. + false } sparse-checkout-cone-mode:{Specifies whether to use cone-mode when doing a sparse checkout. + false true} ssh-key:{SSH key used to fetch the repository. The SSH key is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the SSH key. + +We recommend using a service account with the least permissions necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false } ssh-known-hosts:{Known hosts in addition to the user and global host key database. The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, `ssh-keyscan github.com`. The public key for github.com is always implicitly added. + false } ssh-strict:{Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to configure additional hosts. + false true} ssh-user:{The user to use when connecting to the remote SSH host. By default 'git' is used. + false git} submodules:{Whether to checkout submodules: `true` to checkout submodules or `recursive` to recursively checkout submodules. + +When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are converted to HTTPS. + false false} token:{Personal access token (PAT) used to fetch the repository. The PAT is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the PAT. + +We recommend using a service account with the least permissions necessary. Also when generating a new PAT, select the least scopes necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false ${{ github.token }}}] map[commit:{The commit SHA that was checked out } ref:{The branch, tag or SHA that was checked out }] {node20 map[] dist/index.js always() dist/index.js always() [] []} { }} from 'Unknown' +[CI Pipeline/e2e (webkit)] โ˜ git clone 'https://github.com/actions/setup-node' # ref=v4 +[CI Pipeline/e2e (webkit)] [DEBUG] cloning https://github.com/actions/setup-node to /Users/Vinod/.cache/act/actions-setup-node@v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Unable to pull refs/heads/v4: worktree contains unstaged changes +[CI Pipeline/e2e (webkit)] [DEBUG] Cloned https://github.com/actions/setup-node to /Users/Vinod/.cache/act/actions-setup-node@v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Checked out v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Read action &{Setup Node.js environment GitHub Setup a Node.js environment by adding problem matchers and optionally downloading and adding it to the PATH. map[always-auth:{Set always-auth in npmrc. false false} architecture:{Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default. false } cache:{Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm. false } cache-dependency-path:{Used to specify the path to a dependency file: package-lock.json, yarn.lock, etc. Supports wildcards or a list of file names for caching multiple dependencies. false } check-latest:{Set this option if you want the action to check for the latest available version that satisfies the version spec. false false} mirror:{Used to specify an alternative mirror to downlooad Node.js binaries from false } mirror-token:{The token used as Authorization header when fetching from the mirror false } node-version:{Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0. false } node-version-file:{File containing the version Spec of the version to use. Examples: package.json, .nvmrc, .node-version, .tool-versions. false } registry-url:{Optional registry to set up for auth. Will set the registry in a project level .npmrc and .yarnrc file, and set up auth to read in from env.NODE_AUTH_TOKEN. false } scope:{Optional scope for authenticating against scoped registries. Will fall back to the repository owner when using the GitHub Packages registry (https://npm.pkg.github.com/). false } token:{Used to pull node distributions from node-versions. Since there's a default, this is typically not supplied by the user. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting. false ${{ github.server_url == 'https://github.com' && github.token || '' }}}] map[cache-hit:{A boolean value to indicate if a cache was hit. } node-version:{The installed node version. }] {node20 map[] dist/setup/index.js always() dist/cache-save/index.js success() [] []} { }} from 'Unknown' +[CI Pipeline/e2e (webkit)] โ˜ git clone 'https://github.com/actions/upload-artifact' # ref=v4 +[CI Pipeline/e2e (webkit)] [DEBUG] cloning https://github.com/actions/upload-artifact to /Users/Vinod/.cache/act/actions-upload-artifact@v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Cloned https://github.com/actions/upload-artifact to /Users/Vinod/.cache/act/actions-upload-artifact@v4 +[CI Pipeline/visual-regression] [DEBUG] evaluating expression 'success()' +[CI Pipeline/visual-regression] [DEBUG] expression 'success()' evaluated to 'true' +[CI Pipeline/visual-regression] โ˜ git clone 'https://github.com/actions/checkout' # ref=v4 +[CI Pipeline/visual-regression] [DEBUG] cloning https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Checked out v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Read action &{Upload a Build Artifact GitHub Upload a build artifact that can be used by subsequent workflow steps map[compression-level:{The level of compression for Zlib to be applied to the artifact archive. The value can range from 0 to 9: - 0: No compression - 1: Best speed - 6: Default compression (same as GNU Gzip) - 9: Best compression Higher levels will result in better compression, but will take longer to complete. For large files that are not easily compressed, a value of 0 is recommended for significantly faster uploads. + false 6} if-no-files-found:{The desired behavior if no files are found using the provided path. +Available Options: + warn: Output a warning but do not fail the action + error: Fail the action with an error message + ignore: Do not output any warnings or errors, the action does not fail + false warn} include-hidden-files:{If true, hidden files will be included in the artifact. If false, hidden files will be excluded from the artifact. + false false} name:{Artifact name false artifact} overwrite:{If true, an artifact with a matching name will be deleted before a new one is uploaded. If false, the action will fail if an artifact for the given name already exists. Does not fail if the artifact does not exist. + false false} path:{A file, directory or wildcard pattern that describes what to upload true } retention-days:{Duration after which artifact will expire in days. 0 means using default retention. +Minimum 1 day. Maximum 90 days unless changed from the repository settings page. + false }] map[artifact-digest:{SHA-256 digest for the artifact that was just uploaded. Empty if the artifact upload failed. + } artifact-id:{A unique identifier for the artifact that was just uploaded. Empty if the artifact upload failed. +This ID can be used as input to other APIs to download, delete or get more information about an artifact: https://docs.github.com/en/rest/actions/artifacts + } artifact-url:{A download URL for the artifact that was just uploaded. Empty if the artifact upload failed. +This download URL only works for requests Authenticated with GitHub. Anonymous downloads will be prompted to first login. If an anonymous download URL is needed than a short time restricted URL can be generated using the download artifact API: https://docs.github.com/en/rest/actions/artifacts#download-an-artifact +This URL will be valid for as long as the artifact exists and the workflow run and repository exists. Once an artifact has expired this URL will no longer work. Common uses cases for such a download URL can be adding download links to artifacts in descriptions or comments on pull requests or issues. + }] {node20 map[] dist/upload/index.js always() always() [] []} { }} from 'Unknown' +[CI Pipeline/e2e (webkit)] ๐Ÿงช Matrix: map[browser:webkit] +[CI Pipeline/e2e (webkit)] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:0 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/checkout GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:e2e GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/f42616da4b07b25b/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/f42616da4b07b25b/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression '' +[CI Pipeline/e2e (webkit)] [DEBUG] expression '' evaluated to 'true' +[CI Pipeline/e2e (webkit)] โญ Run Main Checkout code +[CI Pipeline/e2e (webkit)] [DEBUG] About to run action &{Checkout Checkout a Git repository at a particular version map[clean:{Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching false true} fetch-depth:{Number of commits to fetch. 0 indicates all history for all branches and tags. false 1} fetch-tags:{Whether to fetch tags, even if fetch-depth > 0. false false} filter:{Partially clone against a given filter. Overrides sparse-checkout if set. + false } github-server-url:{The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com false } lfs:{Whether to download Git-LFS files false false} path:{Relative path under $GITHUB_WORKSPACE to place the repository false } persist-credentials:{Whether to configure the token or SSH key with the local git config false true} ref:{The branch, tag or SHA to checkout. When checking out the repository that triggered a workflow, this defaults to the reference or SHA for that event. Otherwise, uses the default branch. + false } repository:{Repository name with owner. For example, actions/checkout false ${{ github.repository }}} set-safe-directory:{Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory ` false true} show-progress:{Whether to show progress status output when fetching. false true} sparse-checkout:{Do a sparse checkout on given patterns. Each pattern should be separated with new lines. + false } sparse-checkout-cone-mode:{Specifies whether to use cone-mode when doing a sparse checkout. + false true} ssh-key:{SSH key used to fetch the repository. The SSH key is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the SSH key. + +We recommend using a service account with the least permissions necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false } ssh-known-hosts:{Known hosts in addition to the user and global host key database. The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, `ssh-keyscan github.com`. The public key for github.com is always implicitly added. + false } ssh-strict:{Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to configure additional hosts. + false true} ssh-user:{The user to use when connecting to the remote SSH host. By default 'git' is used. + false git} submodules:{Whether to checkout submodules: `true` to checkout submodules or `recursive` to recursively checkout submodules. + +When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are converted to HTTPS. + false false} token:{Personal access token (PAT) used to fetch the repository. The PAT is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the PAT. + +We recommend using a service account with the least permissions necessary. Also when generating a new PAT, select the least scopes necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false ${{ github.token }}}] map[commit:{The commit SHA that was checked out } ref:{The branch, tag or SHA that was checked out }] {node20 map[] dist/index.js always() dist/index.js always() [] []} { }} +[CI Pipeline/e2e (webkit)] [DEBUG] expression '${{ github.repository }}' rewritten to 'format('{0}', github.repository)' +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression 'format('{0}', github.repository)' +[CI Pipeline/e2e (webkit)] [DEBUG] expression 'format('{0}', github.repository)' evaluated to '%!t(string=CommunityRule/community-rule)' +[CI Pipeline/e2e (webkit)] [DEBUG] expression '${{ github.token }}' rewritten to 'format('{0}', github.token)' +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression 'format('{0}', github.token)' +[CI Pipeline/e2e (webkit)] [DEBUG] expression 'format('{0}', github.token)' evaluated to '%!t(string=***)' +[CI Pipeline/e2e (webkit)] [DEBUG] type=remote-action actionDir=/Users/Vinod/.cache/act/actions-checkout@v4 actionPath= workdir=/workspace/CommunityRule/community-rule actionCacheDir=/Users/Vinod/.cache/act actionName=actions-checkout@v4 containerActionDir=/Users/Vinod/.cache/act/f42616da4b07b25b/act/actions/actions-checkout@v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Removing /Users/Vinod/.cache/act/actions-checkout@v4/.gitignore before docker cp +[CI Pipeline/e2e (webkit)] [DEBUG] /Users/Vinod/.cache/act/f42616da4b07b25b/act/actions/actions-checkout@v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Stripping prefix:/Users/Vinod/.cache/act/actions-checkout@v4/ src:/Users/Vinod/.cache/act/actions-checkout@v4/ +[CI Pipeline/e2e (webkit)] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/f42616da4b07b25b/act/actions/actions-checkout@v4/dist/index.js] +[CI Pipeline/e2e (webkit)] | Cannot find: node in PATH +[CI Pipeline/e2e (webkit)] โŒ Failure - Main Checkout code +[CI Pipeline/e2e (webkit)] Cannot find: node in PATH +[CI Pipeline/e2e (webkit)] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:1 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/setup-node GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:e2e GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/f42616da4b07b25b/hostexecutor HOME:/Users/Vinod INPUT_CACHE:npm INPUT_NODE-VERSION:20 ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/f42616da4b07b25b/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression '' +[CI Pipeline/e2e (webkit)] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/e2e (webkit)] [DEBUG] Skipping step 'Setup Node.js' due to '' +[CI Pipeline/e2e (webkit)] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:2 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:e2e GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/f42616da4b07b25b/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/f42616da4b07b25b/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression '' +[CI Pipeline/e2e (webkit)] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/e2e (webkit)] [DEBUG] Skipping step 'Install dependencies' due to '' +[CI Pipeline/e2e (webkit)] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:3 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:e2e GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/f42616da4b07b25b/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/f42616da4b07b25b/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression '' +[CI Pipeline/e2e (webkit)] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/e2e (webkit)] [DEBUG] Skipping step 'Install Playwright browsers' due to '' +[CI Pipeline/e2e (webkit)] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:4 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:e2e GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/f42616da4b07b25b/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/f42616da4b07b25b/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression '' +[CI Pipeline/e2e (webkit)] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/e2e (webkit)] [DEBUG] Skipping step 'Build application' due to '' +[CI Pipeline/e2e (webkit)] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:5 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:e2e GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/f42616da4b07b25b/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/f42616da4b07b25b/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression '' +[CI Pipeline/e2e (webkit)] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/e2e (webkit)] [DEBUG] Skipping step 'Start application' due to '' +[CI Pipeline/e2e (webkit)] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:6 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:e2e GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/f42616da4b07b25b/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/f42616da4b07b25b/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression '' +[CI Pipeline/e2e (webkit)] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/e2e (webkit)] [DEBUG] Skipping step 'Wait for application to be ready' due to '' +[CI Pipeline/e2e (webkit)] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:7 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:e2e GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/f42616da4b07b25b/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/f42616da4b07b25b/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression '' +[CI Pipeline/e2e (webkit)] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/e2e (webkit)] [DEBUG] Skipping step 'Run E2E tests' due to '' +[CI Pipeline/e2e (webkit)] [DEBUG] expression 'playwright-results-${{ matrix.browser }}' rewritten to 'format('playwright-results-{0}', matrix.browser)' +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression 'format('playwright-results-{0}', matrix.browser)' +[CI Pipeline/e2e (webkit)] [DEBUG] expression 'format('playwright-results-{0}', matrix.browser)' evaluated to '%!t(string=playwright-results-webkit)' +[CI Pipeline/e2e (webkit)] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:8 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/upload-artifact GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:e2e GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/f42616da4b07b25b/hostexecutor HOME:/Users/Vinod INPUT_NAME:playwright-results-webkit INPUT_PATH:test-results/ +playwright-report/ + INPUT_RETENTION-DAYS:30 ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/f42616da4b07b25b/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression 'always()' +[CI Pipeline/e2e (webkit)] [DEBUG] expression 'always()' evaluated to 'true' +[CI Pipeline/e2e (webkit)] โญ Run Main Upload test results +[CI Pipeline/e2e (webkit)] [DEBUG] About to run action &{Upload a Build Artifact GitHub Upload a build artifact that can be used by subsequent workflow steps map[compression-level:{The level of compression for Zlib to be applied to the artifact archive. The value can range from 0 to 9: - 0: No compression - 1: Best speed - 6: Default compression (same as GNU Gzip) - 9: Best compression Higher levels will result in better compression, but will take longer to complete. For large files that are not easily compressed, a value of 0 is recommended for significantly faster uploads. + false 6} if-no-files-found:{The desired behavior if no files are found using the provided path. +Available Options: + warn: Output a warning but do not fail the action + error: Fail the action with an error message + ignore: Do not output any warnings or errors, the action does not fail + false warn} include-hidden-files:{If true, hidden files will be included in the artifact. If false, hidden files will be excluded from the artifact. + false false} name:{Artifact name false artifact} overwrite:{If true, an artifact with a matching name will be deleted before a new one is uploaded. If false, the action will fail if an artifact for the given name already exists. Does not fail if the artifact does not exist. + false false} path:{A file, directory or wildcard pattern that describes what to upload true } retention-days:{Duration after which artifact will expire in days. 0 means using default retention. +Minimum 1 day. Maximum 90 days unless changed from the repository settings page. + false }] map[artifact-digest:{SHA-256 digest for the artifact that was just uploaded. Empty if the artifact upload failed. + } artifact-id:{A unique identifier for the artifact that was just uploaded. Empty if the artifact upload failed. +This ID can be used as input to other APIs to download, delete or get more information about an artifact: https://docs.github.com/en/rest/actions/artifacts + } artifact-url:{A download URL for the artifact that was just uploaded. Empty if the artifact upload failed. +This download URL only works for requests Authenticated with GitHub. Anonymous downloads will be prompted to first login. If an anonymous download URL is needed than a short time restricted URL can be generated using the download artifact API: https://docs.github.com/en/rest/actions/artifacts#download-an-artifact +This URL will be valid for as long as the artifact exists and the workflow run and repository exists. Once an artifact has expired this URL will no longer work. Common uses cases for such a download URL can be adding download links to artifacts in descriptions or comments on pull requests or issues. + }] {node20 map[] dist/upload/index.js always() always() [] []} { }} +[CI Pipeline/e2e (webkit)] [DEBUG] type=remote-action actionDir=/Users/Vinod/.cache/act/actions-upload-artifact@v4 actionPath= workdir=/workspace/CommunityRule/community-rule actionCacheDir=/Users/Vinod/.cache/act actionName=actions-upload-artifact@v4 containerActionDir=/Users/Vinod/.cache/act/f42616da4b07b25b/act/actions/actions-upload-artifact@v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Removing /Users/Vinod/.cache/act/actions-upload-artifact@v4/.gitignore before docker cp +[CI Pipeline/e2e (webkit)] [DEBUG] /Users/Vinod/.cache/act/f42616da4b07b25b/act/actions/actions-upload-artifact@v4 +[CI Pipeline/e2e (webkit)] [DEBUG] Stripping prefix:/Users/Vinod/.cache/act/actions-upload-artifact@v4/ src:/Users/Vinod/.cache/act/actions-upload-artifact@v4/ +[CI Pipeline/visual-regression] [DEBUG] Unable to pull refs/heads/v4: worktree contains unstaged changes +[CI Pipeline/visual-regression] [DEBUG] Cloned https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/visual-regression] [DEBUG] Checked out v4 +[CI Pipeline/visual-regression] [DEBUG] Read action &{Checkout Checkout a Git repository at a particular version map[clean:{Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching false true} fetch-depth:{Number of commits to fetch. 0 indicates all history for all branches and tags. false 1} fetch-tags:{Whether to fetch tags, even if fetch-depth > 0. false false} filter:{Partially clone against a given filter. Overrides sparse-checkout if set. + false } github-server-url:{The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com false } lfs:{Whether to download Git-LFS files false false} path:{Relative path under $GITHUB_WORKSPACE to place the repository false } persist-credentials:{Whether to configure the token or SSH key with the local git config false true} ref:{The branch, tag or SHA to checkout. When checking out the repository that triggered a workflow, this defaults to the reference or SHA for that event. Otherwise, uses the default branch. + false } repository:{Repository name with owner. For example, actions/checkout false ${{ github.repository }}} set-safe-directory:{Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory ` false true} show-progress:{Whether to show progress status output when fetching. false true} sparse-checkout:{Do a sparse checkout on given patterns. Each pattern should be separated with new lines. + false } sparse-checkout-cone-mode:{Specifies whether to use cone-mode when doing a sparse checkout. + false true} ssh-key:{SSH key used to fetch the repository. The SSH key is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the SSH key. + +We recommend using a service account with the least permissions necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false } ssh-known-hosts:{Known hosts in addition to the user and global host key database. The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, `ssh-keyscan github.com`. The public key for github.com is always implicitly added. + false } ssh-strict:{Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to configure additional hosts. + false true} ssh-user:{The user to use when connecting to the remote SSH host. By default 'git' is used. + false git} submodules:{Whether to checkout submodules: `true` to checkout submodules or `recursive` to recursively checkout submodules. + +When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are converted to HTTPS. + false false} token:{Personal access token (PAT) used to fetch the repository. The PAT is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the PAT. + +We recommend using a service account with the least permissions necessary. Also when generating a new PAT, select the least scopes necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false ${{ github.token }}}] map[commit:{The commit SHA that was checked out } ref:{The branch, tag or SHA that was checked out }] {node20 map[] dist/index.js always() dist/index.js always() [] []} { }} from 'Unknown' +[CI Pipeline/visual-regression] โ˜ git clone 'https://github.com/actions/setup-node' # ref=v4 +[CI Pipeline/visual-regression] [DEBUG] cloning https://github.com/actions/setup-node to /Users/Vinod/.cache/act/actions-setup-node@v4 +[CI Pipeline/e2e (webkit)] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/f42616da4b07b25b/act/actions/actions-upload-artifact@v4/dist/upload/index.js] +[CI Pipeline/e2e (webkit)] | Cannot find: node in PATH +[CI Pipeline/e2e (webkit)] โŒ Failure - Main Upload test results +[CI Pipeline/e2e (webkit)] Cannot find: node in PATH +[CI Pipeline/e2e (webkit)] [DEBUG] skipping post step for 'Setup Node.js'; main step was skipped +[CI Pipeline/e2e (webkit)] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:0 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/checkout GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_ENV:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/envs.txt GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:e2e GITHUB_OUTPUT:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/outputcmd.txt GITHUB_PATH:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/pathcmd.txt GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_STATE:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/statecmd.txt GITHUB_STEP_SUMMARY:/Users/Vinod/.cache/act/f42616da4b07b25b/act/workflow/SUMMARY.md GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/f42616da4b07b25b/hostexecutor HOME:/Users/Vinod INPUT_CLEAN:true INPUT_FETCH-DEPTH:1 INPUT_FETCH-TAGS:false INPUT_FILTER: INPUT_GITHUB-SERVER-URL: INPUT_LFS:false INPUT_PATH: INPUT_PERSIST-CREDENTIALS:true INPUT_REF: INPUT_REPOSITORY:CommunityRule/community-rule INPUT_SET-SAFE-DIRECTORY:true INPUT_SHOW-PROGRESS:true INPUT_SPARSE-CHECKOUT: INPUT_SPARSE-CHECKOUT-CONE-MODE:true INPUT_SSH-KEY: INPUT_SSH-KNOWN-HOSTS: INPUT_SSH-STRICT:true INPUT_SSH-USER:git INPUT_SUBMODULES:false INPUT_TOKEN:*** ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/f42616da4b07b25b/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/e2e (webkit)] [DEBUG] evaluating expression 'always()' +[CI Pipeline/e2e (webkit)] [DEBUG] expression 'always()' evaluated to 'true' +[CI Pipeline/e2e (webkit)] โญ Run Post Checkout code +[CI Pipeline/e2e (webkit)] [DEBUG] run post step for 'Checkout code' +[CI Pipeline/e2e (webkit)] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/f42616da4b07b25b/act/actions/actions-checkout@v4/dist/index.js] +[CI Pipeline/e2e (webkit)] | Cannot find: node in PATH +[CI Pipeline/e2e (webkit)] โŒ Failure - Post Checkout code +[CI Pipeline/e2e (webkit)] Cleaning up services for job e2e (webkit) +[CI Pipeline/e2e (webkit)] Cleaning up container for job e2e (webkit) +[CI Pipeline/e2e (webkit)] ๐Ÿ Job failed +[CI Pipeline/visual-regression] [DEBUG] Cloned https://github.com/actions/setup-node to /Users/Vinod/.cache/act/actions-setup-node@v4 +[CI Pipeline/visual-regression] [DEBUG] Checked out v4 +[CI Pipeline/visual-regression] [DEBUG] Read action &{Setup Node.js environment GitHub Setup a Node.js environment by adding problem matchers and optionally downloading and adding it to the PATH. map[always-auth:{Set always-auth in npmrc. false false} architecture:{Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default. false } cache:{Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm. false } cache-dependency-path:{Used to specify the path to a dependency file: package-lock.json, yarn.lock, etc. Supports wildcards or a list of file names for caching multiple dependencies. false } check-latest:{Set this option if you want the action to check for the latest available version that satisfies the version spec. false false} mirror:{Used to specify an alternative mirror to downlooad Node.js binaries from false } mirror-token:{The token used as Authorization header when fetching from the mirror false } node-version:{Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0. false } node-version-file:{File containing the version Spec of the version to use. Examples: package.json, .nvmrc, .node-version, .tool-versions. false } registry-url:{Optional registry to set up for auth. Will set the registry in a project level .npmrc and .yarnrc file, and set up auth to read in from env.NODE_AUTH_TOKEN. false } scope:{Optional scope for authenticating against scoped registries. Will fall back to the repository owner when using the GitHub Packages registry (https://npm.pkg.github.com/). false } token:{Used to pull node distributions from node-versions. Since there's a default, this is typically not supplied by the user. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting. false ${{ github.server_url == 'https://github.com' && github.token || '' }}}] map[cache-hit:{A boolean value to indicate if a cache was hit. } node-version:{The installed node version. }] {node20 map[] dist/setup/index.js always() dist/cache-save/index.js success() [] []} { }} from 'Unknown' +[CI Pipeline/visual-regression] โ˜ git clone 'https://github.com/actions/upload-artifact' # ref=v4 +[CI Pipeline/visual-regression] [DEBUG] cloning https://github.com/actions/upload-artifact to /Users/Vinod/.cache/act/actions-upload-artifact@v4 +[CI Pipeline/visual-regression] [DEBUG] Unable to pull refs/heads/v4: worktree contains unstaged changes +[CI Pipeline/visual-regression] [DEBUG] Cloned https://github.com/actions/upload-artifact to /Users/Vinod/.cache/act/actions-upload-artifact@v4 +[CI Pipeline/visual-regression] [DEBUG] Checked out v4 +[CI Pipeline/visual-regression] [DEBUG] Read action &{Upload a Build Artifact GitHub Upload a build artifact that can be used by subsequent workflow steps map[compression-level:{The level of compression for Zlib to be applied to the artifact archive. The value can range from 0 to 9: - 0: No compression - 1: Best speed - 6: Default compression (same as GNU Gzip) - 9: Best compression Higher levels will result in better compression, but will take longer to complete. For large files that are not easily compressed, a value of 0 is recommended for significantly faster uploads. + false 6} if-no-files-found:{The desired behavior if no files are found using the provided path. +Available Options: + warn: Output a warning but do not fail the action + error: Fail the action with an error message + ignore: Do not output any warnings or errors, the action does not fail + false warn} include-hidden-files:{If true, hidden files will be included in the artifact. If false, hidden files will be excluded from the artifact. + false false} name:{Artifact name false artifact} overwrite:{If true, an artifact with a matching name will be deleted before a new one is uploaded. If false, the action will fail if an artifact for the given name already exists. Does not fail if the artifact does not exist. + false false} path:{A file, directory or wildcard pattern that describes what to upload true } retention-days:{Duration after which artifact will expire in days. 0 means using default retention. +Minimum 1 day. Maximum 90 days unless changed from the repository settings page. + false }] map[artifact-digest:{SHA-256 digest for the artifact that was just uploaded. Empty if the artifact upload failed. + } artifact-id:{A unique identifier for the artifact that was just uploaded. Empty if the artifact upload failed. +This ID can be used as input to other APIs to download, delete or get more information about an artifact: https://docs.github.com/en/rest/actions/artifacts + } artifact-url:{A download URL for the artifact that was just uploaded. Empty if the artifact upload failed. +This download URL only works for requests Authenticated with GitHub. Anonymous downloads will be prompted to first login. If an anonymous download URL is needed than a short time restricted URL can be generated using the download artifact API: https://docs.github.com/en/rest/actions/artifacts#download-an-artifact +This URL will be valid for as long as the artifact exists and the workflow run and repository exists. Once an artifact has expired this URL will no longer work. Common uses cases for such a download URL can be adding download links to artifacts in descriptions or comments on pull requests or issues. + }] {node20 map[] dist/upload/index.js always() always() [] []} { }} from 'Unknown' +[CI Pipeline/visual-regression] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:0 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/checkout GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:visual-regression GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2746df9b70b8df36/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2746df9b70b8df36/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/visual-regression] [DEBUG] evaluating expression '' +[CI Pipeline/visual-regression] [DEBUG] expression '' evaluated to 'true' +[CI Pipeline/visual-regression] โญ Run Main Checkout code +[CI Pipeline/visual-regression] [DEBUG] About to run action &{Checkout Checkout a Git repository at a particular version map[clean:{Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching false true} fetch-depth:{Number of commits to fetch. 0 indicates all history for all branches and tags. false 1} fetch-tags:{Whether to fetch tags, even if fetch-depth > 0. false false} filter:{Partially clone against a given filter. Overrides sparse-checkout if set. + false } github-server-url:{The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com false } lfs:{Whether to download Git-LFS files false false} path:{Relative path under $GITHUB_WORKSPACE to place the repository false } persist-credentials:{Whether to configure the token or SSH key with the local git config false true} ref:{The branch, tag or SHA to checkout. When checking out the repository that triggered a workflow, this defaults to the reference or SHA for that event. Otherwise, uses the default branch. + false } repository:{Repository name with owner. For example, actions/checkout false ${{ github.repository }}} set-safe-directory:{Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory ` false true} show-progress:{Whether to show progress status output when fetching. false true} sparse-checkout:{Do a sparse checkout on given patterns. Each pattern should be separated with new lines. + false } sparse-checkout-cone-mode:{Specifies whether to use cone-mode when doing a sparse checkout. + false true} ssh-key:{SSH key used to fetch the repository. The SSH key is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the SSH key. + +We recommend using a service account with the least permissions necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false } ssh-known-hosts:{Known hosts in addition to the user and global host key database. The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, `ssh-keyscan github.com`. The public key for github.com is always implicitly added. + false } ssh-strict:{Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to configure additional hosts. + false true} ssh-user:{The user to use when connecting to the remote SSH host. By default 'git' is used. + false git} submodules:{Whether to checkout submodules: `true` to checkout submodules or `recursive` to recursively checkout submodules. + +When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are converted to HTTPS. + false false} token:{Personal access token (PAT) used to fetch the repository. The PAT is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the PAT. + +We recommend using a service account with the least permissions necessary. Also when generating a new PAT, select the least scopes necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false ${{ github.token }}}] map[commit:{The commit SHA that was checked out } ref:{The branch, tag or SHA that was checked out }] {node20 map[] dist/index.js always() dist/index.js always() [] []} { }} +[CI Pipeline/visual-regression] [DEBUG] expression '${{ github.token }}' rewritten to 'format('{0}', github.token)' +[CI Pipeline/visual-regression] [DEBUG] evaluating expression 'format('{0}', github.token)' +[CI Pipeline/visual-regression] [DEBUG] expression 'format('{0}', github.token)' evaluated to '%!t(string=***)' +[CI Pipeline/visual-regression] [DEBUG] expression '${{ github.repository }}' rewritten to 'format('{0}', github.repository)' +[CI Pipeline/visual-regression] [DEBUG] evaluating expression 'format('{0}', github.repository)' +[CI Pipeline/visual-regression] [DEBUG] expression 'format('{0}', github.repository)' evaluated to '%!t(string=CommunityRule/community-rule)' +[CI Pipeline/visual-regression] [DEBUG] type=remote-action actionDir=/Users/Vinod/.cache/act/actions-checkout@v4 actionPath= workdir=/workspace/CommunityRule/community-rule actionCacheDir=/Users/Vinod/.cache/act actionName=actions-checkout@v4 containerActionDir=/Users/Vinod/.cache/act/2746df9b70b8df36/act/actions/actions-checkout@v4 +[CI Pipeline/visual-regression] [DEBUG] Removing /Users/Vinod/.cache/act/actions-checkout@v4/.gitignore before docker cp +[CI Pipeline/visual-regression] [DEBUG] /Users/Vinod/.cache/act/2746df9b70b8df36/act/actions/actions-checkout@v4 +[CI Pipeline/visual-regression] [DEBUG] Stripping prefix:/Users/Vinod/.cache/act/actions-checkout@v4/ src:/Users/Vinod/.cache/act/actions-checkout@v4/ +[CI Pipeline/visual-regression] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/2746df9b70b8df36/act/actions/actions-checkout@v4/dist/index.js] +[CI Pipeline/visual-regression] | Cannot find: node in PATH +[CI Pipeline/visual-regression] โŒ Failure - Main Checkout code +[CI Pipeline/visual-regression] Cannot find: node in PATH +[CI Pipeline/visual-regression] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:1 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/setup-node GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:visual-regression GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2746df9b70b8df36/hostexecutor HOME:/Users/Vinod INPUT_CACHE:npm INPUT_NODE-VERSION:20 ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2746df9b70b8df36/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/visual-regression] [DEBUG] evaluating expression '' +[CI Pipeline/visual-regression] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/visual-regression] [DEBUG] Skipping step 'Setup Node.js' due to '' +[CI Pipeline/visual-regression] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:2 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:visual-regression GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2746df9b70b8df36/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2746df9b70b8df36/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/visual-regression] [DEBUG] evaluating expression '' +[CI Pipeline/visual-regression] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/visual-regression] [DEBUG] Skipping step 'Install dependencies' due to '' +[CI Pipeline/visual-regression] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:3 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:visual-regression GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2746df9b70b8df36/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2746df9b70b8df36/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/visual-regression] [DEBUG] evaluating expression '' +[CI Pipeline/visual-regression] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/visual-regression] [DEBUG] Skipping step 'Install Playwright browsers' due to '' +[CI Pipeline/visual-regression] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:4 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:visual-regression GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2746df9b70b8df36/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2746df9b70b8df36/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/visual-regression] [DEBUG] evaluating expression '' +[CI Pipeline/visual-regression] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/visual-regression] [DEBUG] Skipping step 'Build application' due to '' +[CI Pipeline/visual-regression] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:5 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:visual-regression GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2746df9b70b8df36/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2746df9b70b8df36/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/visual-regression] [DEBUG] evaluating expression '' +[CI Pipeline/visual-regression] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/visual-regression] [DEBUG] Skipping step 'Start application' due to '' +[CI Pipeline/visual-regression] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:6 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:visual-regression GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2746df9b70b8df36/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2746df9b70b8df36/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/visual-regression] [DEBUG] evaluating expression '' +[CI Pipeline/visual-regression] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/visual-regression] [DEBUG] Skipping step 'Wait for application to be ready' due to '' +[CI Pipeline/visual-regression] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:7 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:visual-regression GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2746df9b70b8df36/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2746df9b70b8df36/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/visual-regression] [DEBUG] evaluating expression '' +[CI Pipeline/visual-regression] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/visual-regression] [DEBUG] Skipping step 'Run visual regression tests' due to '' +[CI Pipeline/visual-regression] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:8 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/upload-artifact GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:visual-regression GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2746df9b70b8df36/hostexecutor HOME:/Users/Vinod INPUT_NAME:visual-regression-results INPUT_PATH:test-results/ +tests/e2e/visual-regression.spec.ts-snapshots/ + INPUT_RETENTION-DAYS:30 ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2746df9b70b8df36/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/visual-regression] [DEBUG] evaluating expression 'always()' +[CI Pipeline/visual-regression] [DEBUG] expression 'always()' evaluated to 'true' +[CI Pipeline/visual-regression] โญ Run Main Upload visual regression results +[CI Pipeline/visual-regression] [DEBUG] About to run action &{Upload a Build Artifact GitHub Upload a build artifact that can be used by subsequent workflow steps map[compression-level:{The level of compression for Zlib to be applied to the artifact archive. The value can range from 0 to 9: - 0: No compression - 1: Best speed - 6: Default compression (same as GNU Gzip) - 9: Best compression Higher levels will result in better compression, but will take longer to complete. For large files that are not easily compressed, a value of 0 is recommended for significantly faster uploads. + false 6} if-no-files-found:{The desired behavior if no files are found using the provided path. +Available Options: + warn: Output a warning but do not fail the action + error: Fail the action with an error message + ignore: Do not output any warnings or errors, the action does not fail + false warn} include-hidden-files:{If true, hidden files will be included in the artifact. If false, hidden files will be excluded from the artifact. + false false} name:{Artifact name false artifact} overwrite:{If true, an artifact with a matching name will be deleted before a new one is uploaded. If false, the action will fail if an artifact for the given name already exists. Does not fail if the artifact does not exist. + false false} path:{A file, directory or wildcard pattern that describes what to upload true } retention-days:{Duration after which artifact will expire in days. 0 means using default retention. +Minimum 1 day. Maximum 90 days unless changed from the repository settings page. + false }] map[artifact-digest:{SHA-256 digest for the artifact that was just uploaded. Empty if the artifact upload failed. + } artifact-id:{A unique identifier for the artifact that was just uploaded. Empty if the artifact upload failed. +This ID can be used as input to other APIs to download, delete or get more information about an artifact: https://docs.github.com/en/rest/actions/artifacts + } artifact-url:{A download URL for the artifact that was just uploaded. Empty if the artifact upload failed. +This download URL only works for requests Authenticated with GitHub. Anonymous downloads will be prompted to first login. If an anonymous download URL is needed than a short time restricted URL can be generated using the download artifact API: https://docs.github.com/en/rest/actions/artifacts#download-an-artifact +This URL will be valid for as long as the artifact exists and the workflow run and repository exists. Once an artifact has expired this URL will no longer work. Common uses cases for such a download URL can be adding download links to artifacts in descriptions or comments on pull requests or issues. + }] {node20 map[] dist/upload/index.js always() always() [] []} { }} +[CI Pipeline/visual-regression] [DEBUG] type=remote-action actionDir=/Users/Vinod/.cache/act/actions-upload-artifact@v4 actionPath= workdir=/workspace/CommunityRule/community-rule actionCacheDir=/Users/Vinod/.cache/act actionName=actions-upload-artifact@v4 containerActionDir=/Users/Vinod/.cache/act/2746df9b70b8df36/act/actions/actions-upload-artifact@v4 +[CI Pipeline/visual-regression] [DEBUG] Removing /Users/Vinod/.cache/act/actions-upload-artifact@v4/.gitignore before docker cp +[CI Pipeline/visual-regression] [DEBUG] /Users/Vinod/.cache/act/2746df9b70b8df36/act/actions/actions-upload-artifact@v4 +[CI Pipeline/visual-regression] [DEBUG] Stripping prefix:/Users/Vinod/.cache/act/actions-upload-artifact@v4/ src:/Users/Vinod/.cache/act/actions-upload-artifact@v4/ +[CI Pipeline/performance] [DEBUG] evaluating expression 'success()' +[CI Pipeline/performance] [DEBUG] expression 'success()' evaluated to 'true' +[CI Pipeline/performance] โ˜ git clone 'https://github.com/actions/checkout' # ref=v4 +[CI Pipeline/performance] [DEBUG] cloning https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/visual-regression] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/2746df9b70b8df36/act/actions/actions-upload-artifact@v4/dist/upload/index.js] +[CI Pipeline/visual-regression] | Cannot find: node in PATH +[CI Pipeline/visual-regression] โŒ Failure - Main Upload visual regression results +[CI Pipeline/visual-regression] Cannot find: node in PATH +[CI Pipeline/visual-regression] [DEBUG] skipping post step for 'Setup Node.js'; main step was skipped +[CI Pipeline/visual-regression] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:0 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/checkout GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_ENV:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/envs.txt GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:visual-regression GITHUB_OUTPUT:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/outputcmd.txt GITHUB_PATH:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/pathcmd.txt GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_STATE:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/statecmd.txt GITHUB_STEP_SUMMARY:/Users/Vinod/.cache/act/2746df9b70b8df36/act/workflow/SUMMARY.md GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2746df9b70b8df36/hostexecutor HOME:/Users/Vinod INPUT_CLEAN:true INPUT_FETCH-DEPTH:1 INPUT_FETCH-TAGS:false INPUT_FILTER: INPUT_GITHUB-SERVER-URL: INPUT_LFS:false INPUT_PATH: INPUT_PERSIST-CREDENTIALS:true INPUT_REF: INPUT_REPOSITORY:CommunityRule/community-rule INPUT_SET-SAFE-DIRECTORY:true INPUT_SHOW-PROGRESS:true INPUT_SPARSE-CHECKOUT: INPUT_SPARSE-CHECKOUT-CONE-MODE:true INPUT_SSH-KEY: INPUT_SSH-KNOWN-HOSTS: INPUT_SSH-STRICT:true INPUT_SSH-USER:git INPUT_SUBMODULES:false INPUT_TOKEN:*** ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2746df9b70b8df36/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/visual-regression] [DEBUG] evaluating expression 'always()' +[CI Pipeline/visual-regression] [DEBUG] expression 'always()' evaluated to 'true' +[CI Pipeline/visual-regression] โญ Run Post Checkout code +[CI Pipeline/visual-regression] [DEBUG] run post step for 'Checkout code' +[CI Pipeline/visual-regression] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/2746df9b70b8df36/act/actions/actions-checkout@v4/dist/index.js] +[CI Pipeline/visual-regression] | Cannot find: node in PATH +[CI Pipeline/visual-regression] โŒ Failure - Post Checkout code +[CI Pipeline/visual-regression] Cleaning up services for job visual-regression +[CI Pipeline/visual-regression] Cleaning up container for job visual-regression +[CI Pipeline/visual-regression] ๐Ÿ Job failed +[CI Pipeline/performance] [DEBUG] Unable to pull refs/heads/v4: worktree contains unstaged changes +[CI Pipeline/performance] [DEBUG] Cloned https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/performance] [DEBUG] Checked out v4 +[CI Pipeline/performance] [DEBUG] Read action &{Checkout Checkout a Git repository at a particular version map[clean:{Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching false true} fetch-depth:{Number of commits to fetch. 0 indicates all history for all branches and tags. false 1} fetch-tags:{Whether to fetch tags, even if fetch-depth > 0. false false} filter:{Partially clone against a given filter. Overrides sparse-checkout if set. + false } github-server-url:{The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com false } lfs:{Whether to download Git-LFS files false false} path:{Relative path under $GITHUB_WORKSPACE to place the repository false } persist-credentials:{Whether to configure the token or SSH key with the local git config false true} ref:{The branch, tag or SHA to checkout. When checking out the repository that triggered a workflow, this defaults to the reference or SHA for that event. Otherwise, uses the default branch. + false } repository:{Repository name with owner. For example, actions/checkout false ${{ github.repository }}} set-safe-directory:{Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory ` false true} show-progress:{Whether to show progress status output when fetching. false true} sparse-checkout:{Do a sparse checkout on given patterns. Each pattern should be separated with new lines. + false } sparse-checkout-cone-mode:{Specifies whether to use cone-mode when doing a sparse checkout. + false true} ssh-key:{SSH key used to fetch the repository. The SSH key is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the SSH key. + +We recommend using a service account with the least permissions necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false } ssh-known-hosts:{Known hosts in addition to the user and global host key database. The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, `ssh-keyscan github.com`. The public key for github.com is always implicitly added. + false } ssh-strict:{Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to configure additional hosts. + false true} ssh-user:{The user to use when connecting to the remote SSH host. By default 'git' is used. + false git} submodules:{Whether to checkout submodules: `true` to checkout submodules or `recursive` to recursively checkout submodules. + +When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are converted to HTTPS. + false false} token:{Personal access token (PAT) used to fetch the repository. The PAT is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the PAT. + +We recommend using a service account with the least permissions necessary. Also when generating a new PAT, select the least scopes necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false ${{ github.token }}}] map[commit:{The commit SHA that was checked out } ref:{The branch, tag or SHA that was checked out }] {node20 map[] dist/index.js always() dist/index.js always() [] []} { }} from 'Unknown' +[CI Pipeline/performance] โ˜ git clone 'https://github.com/actions/setup-node' # ref=v4 +[CI Pipeline/performance] [DEBUG] cloning https://github.com/actions/setup-node to /Users/Vinod/.cache/act/actions-setup-node@v4 +[CI Pipeline/performance] [DEBUG] Cloned https://github.com/actions/setup-node to /Users/Vinod/.cache/act/actions-setup-node@v4 +[CI Pipeline/performance] [DEBUG] Checked out v4 +[CI Pipeline/performance] [DEBUG] Read action &{Setup Node.js environment GitHub Setup a Node.js environment by adding problem matchers and optionally downloading and adding it to the PATH. map[always-auth:{Set always-auth in npmrc. false false} architecture:{Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default. false } cache:{Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm. false } cache-dependency-path:{Used to specify the path to a dependency file: package-lock.json, yarn.lock, etc. Supports wildcards or a list of file names for caching multiple dependencies. false } check-latest:{Set this option if you want the action to check for the latest available version that satisfies the version spec. false false} mirror:{Used to specify an alternative mirror to downlooad Node.js binaries from false } mirror-token:{The token used as Authorization header when fetching from the mirror false } node-version:{Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0. false } node-version-file:{File containing the version Spec of the version to use. Examples: package.json, .nvmrc, .node-version, .tool-versions. false } registry-url:{Optional registry to set up for auth. Will set the registry in a project level .npmrc and .yarnrc file, and set up auth to read in from env.NODE_AUTH_TOKEN. false } scope:{Optional scope for authenticating against scoped registries. Will fall back to the repository owner when using the GitHub Packages registry (https://npm.pkg.github.com/). false } token:{Used to pull node distributions from node-versions. Since there's a default, this is typically not supplied by the user. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting. false ${{ github.server_url == 'https://github.com' && github.token || '' }}}] map[cache-hit:{A boolean value to indicate if a cache was hit. } node-version:{The installed node version. }] {node20 map[] dist/setup/index.js always() dist/cache-save/index.js success() [] []} { }} from 'Unknown' +[CI Pipeline/performance] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:0 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/checkout GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:performance GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/performance] [DEBUG] evaluating expression '' +[CI Pipeline/performance] [DEBUG] expression '' evaluated to 'true' +[CI Pipeline/performance] โญ Run Main Checkout code +[CI Pipeline/performance] [DEBUG] About to run action &{Checkout Checkout a Git repository at a particular version map[clean:{Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching false true} fetch-depth:{Number of commits to fetch. 0 indicates all history for all branches and tags. false 1} fetch-tags:{Whether to fetch tags, even if fetch-depth > 0. false false} filter:{Partially clone against a given filter. Overrides sparse-checkout if set. + false } github-server-url:{The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com false } lfs:{Whether to download Git-LFS files false false} path:{Relative path under $GITHUB_WORKSPACE to place the repository false } persist-credentials:{Whether to configure the token or SSH key with the local git config false true} ref:{The branch, tag or SHA to checkout. When checking out the repository that triggered a workflow, this defaults to the reference or SHA for that event. Otherwise, uses the default branch. + false } repository:{Repository name with owner. For example, actions/checkout false ${{ github.repository }}} set-safe-directory:{Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory ` false true} show-progress:{Whether to show progress status output when fetching. false true} sparse-checkout:{Do a sparse checkout on given patterns. Each pattern should be separated with new lines. + false } sparse-checkout-cone-mode:{Specifies whether to use cone-mode when doing a sparse checkout. + false true} ssh-key:{SSH key used to fetch the repository. The SSH key is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the SSH key. + +We recommend using a service account with the least permissions necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false } ssh-known-hosts:{Known hosts in addition to the user and global host key database. The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, `ssh-keyscan github.com`. The public key for github.com is always implicitly added. + false } ssh-strict:{Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to configure additional hosts. + false true} ssh-user:{The user to use when connecting to the remote SSH host. By default 'git' is used. + false git} submodules:{Whether to checkout submodules: `true` to checkout submodules or `recursive` to recursively checkout submodules. + +When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are converted to HTTPS. + false false} token:{Personal access token (PAT) used to fetch the repository. The PAT is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the PAT. + +We recommend using a service account with the least permissions necessary. Also when generating a new PAT, select the least scopes necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false ${{ github.token }}}] map[commit:{The commit SHA that was checked out } ref:{The branch, tag or SHA that was checked out }] {node20 map[] dist/index.js always() dist/index.js always() [] []} { }} +[CI Pipeline/performance] [DEBUG] expression '${{ github.repository }}' rewritten to 'format('{0}', github.repository)' +[CI Pipeline/performance] [DEBUG] evaluating expression 'format('{0}', github.repository)' +[CI Pipeline/performance] [DEBUG] expression 'format('{0}', github.repository)' evaluated to '%!t(string=CommunityRule/community-rule)' +[CI Pipeline/performance] [DEBUG] expression '${{ github.token }}' rewritten to 'format('{0}', github.token)' +[CI Pipeline/performance] [DEBUG] evaluating expression 'format('{0}', github.token)' +[CI Pipeline/performance] [DEBUG] expression 'format('{0}', github.token)' evaluated to '%!t(string=***)' +[CI Pipeline/performance] [DEBUG] type=remote-action actionDir=/Users/Vinod/.cache/act/actions-checkout@v4 actionPath= workdir=/workspace/CommunityRule/community-rule actionCacheDir=/Users/Vinod/.cache/act actionName=actions-checkout@v4 containerActionDir=/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/actions/actions-checkout@v4 +[CI Pipeline/performance] [DEBUG] Removing /Users/Vinod/.cache/act/actions-checkout@v4/.gitignore before docker cp +[CI Pipeline/performance] [DEBUG] /Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/actions/actions-checkout@v4 +[CI Pipeline/performance] [DEBUG] Stripping prefix:/Users/Vinod/.cache/act/actions-checkout@v4/ src:/Users/Vinod/.cache/act/actions-checkout@v4/ +[CI Pipeline/performance] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/actions/actions-checkout@v4/dist/index.js] +[CI Pipeline/performance] | Cannot find: node in PATH +[CI Pipeline/performance] โŒ Failure - Main Checkout code +[CI Pipeline/performance] Cannot find: node in PATH +[CI Pipeline/performance] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:1 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/setup-node GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:performance GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/hostexecutor HOME:/Users/Vinod INPUT_CACHE:npm INPUT_NODE-VERSION:20 ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/performance] [DEBUG] evaluating expression '' +[CI Pipeline/performance] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/performance] [DEBUG] Skipping step 'Setup Node.js' due to '' +[CI Pipeline/performance] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:2 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:performance GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/performance] [DEBUG] evaluating expression '' +[CI Pipeline/performance] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/performance] [DEBUG] Skipping step 'Install dependencies' due to '' +[CI Pipeline/performance] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:3 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:performance GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/performance] [DEBUG] evaluating expression '' +[CI Pipeline/performance] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/performance] [DEBUG] Skipping step 'Build application' due to '' +[CI Pipeline/performance] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:4 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:performance GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/performance] [DEBUG] evaluating expression '' +[CI Pipeline/performance] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/performance] [DEBUG] Skipping step 'Start application' due to '' +[CI Pipeline/performance] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:5 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:performance GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/performance] [DEBUG] evaluating expression '' +[CI Pipeline/performance] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/performance] [DEBUG] Skipping step 'Wait for application to be ready' due to '' +[CI Pipeline/performance] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:6 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:performance GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/performance] [DEBUG] evaluating expression '' +[CI Pipeline/performance] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/performance] [DEBUG] Skipping step 'Run Lighthouse CI' due to '' +[CI Pipeline/performance] [DEBUG] skipping post step for 'Setup Node.js'; main step was skipped +[CI Pipeline/performance] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:0 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/checkout GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_ENV:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/envs.txt GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:performance GITHUB_OUTPUT:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/outputcmd.txt GITHUB_PATH:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/pathcmd.txt GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_STATE:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/statecmd.txt GITHUB_STEP_SUMMARY:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/workflow/SUMMARY.md GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/hostexecutor HOME:/Users/Vinod INPUT_CLEAN:true INPUT_FETCH-DEPTH:1 INPUT_FETCH-TAGS:false INPUT_FILTER: INPUT_GITHUB-SERVER-URL: INPUT_LFS:false INPUT_PATH: INPUT_PERSIST-CREDENTIALS:true INPUT_REF: INPUT_REPOSITORY:CommunityRule/community-rule INPUT_SET-SAFE-DIRECTORY:true INPUT_SHOW-PROGRESS:true INPUT_SPARSE-CHECKOUT: INPUT_SPARSE-CHECKOUT-CONE-MODE:true INPUT_SSH-KEY: INPUT_SSH-KNOWN-HOSTS: INPUT_SSH-STRICT:true INPUT_SSH-USER:git INPUT_SUBMODULES:false INPUT_TOKEN:*** ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/2f6e97e8bd8dbf97/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/performance] [DEBUG] evaluating expression 'always()' +[CI Pipeline/performance] [DEBUG] expression 'always()' evaluated to 'true' +[CI Pipeline/performance] โญ Run Post Checkout code +[CI Pipeline/performance] [DEBUG] run post step for 'Checkout code' +[CI Pipeline/performance] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/2f6e97e8bd8dbf97/act/actions/actions-checkout@v4/dist/index.js] +[CI Pipeline/performance] | Cannot find: node in PATH +[CI Pipeline/performance] โŒ Failure - Post Checkout code +[CI Pipeline/performance] Cleaning up services for job performance +[CI Pipeline/performance] Cleaning up container for job performance +[CI Pipeline/performance] ๐Ÿ Job failed +[CI Pipeline/storybook] [DEBUG] evaluating expression 'success()' +[CI Pipeline/storybook] [DEBUG] expression 'success()' evaluated to 'true' +[CI Pipeline/storybook] โ˜ git clone 'https://github.com/actions/checkout' # ref=v4 +[CI Pipeline/storybook] [DEBUG] cloning https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/storybook] [DEBUG] Unable to pull refs/heads/v4: worktree contains unstaged changes +[CI Pipeline/storybook] [DEBUG] Cloned https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/storybook] [DEBUG] Checked out v4 +[CI Pipeline/storybook] [DEBUG] Read action &{Checkout Checkout a Git repository at a particular version map[clean:{Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching false true} fetch-depth:{Number of commits to fetch. 0 indicates all history for all branches and tags. false 1} fetch-tags:{Whether to fetch tags, even if fetch-depth > 0. false false} filter:{Partially clone against a given filter. Overrides sparse-checkout if set. + false } github-server-url:{The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com false } lfs:{Whether to download Git-LFS files false false} path:{Relative path under $GITHUB_WORKSPACE to place the repository false } persist-credentials:{Whether to configure the token or SSH key with the local git config false true} ref:{The branch, tag or SHA to checkout. When checking out the repository that triggered a workflow, this defaults to the reference or SHA for that event. Otherwise, uses the default branch. + false } repository:{Repository name with owner. For example, actions/checkout false ${{ github.repository }}} set-safe-directory:{Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory ` false true} show-progress:{Whether to show progress status output when fetching. false true} sparse-checkout:{Do a sparse checkout on given patterns. Each pattern should be separated with new lines. + false } sparse-checkout-cone-mode:{Specifies whether to use cone-mode when doing a sparse checkout. + false true} ssh-key:{SSH key used to fetch the repository. The SSH key is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the SSH key. + +We recommend using a service account with the least permissions necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false } ssh-known-hosts:{Known hosts in addition to the user and global host key database. The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, `ssh-keyscan github.com`. The public key for github.com is always implicitly added. + false } ssh-strict:{Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to configure additional hosts. + false true} ssh-user:{The user to use when connecting to the remote SSH host. By default 'git' is used. + false git} submodules:{Whether to checkout submodules: `true` to checkout submodules or `recursive` to recursively checkout submodules. + +When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are converted to HTTPS. + false false} token:{Personal access token (PAT) used to fetch the repository. The PAT is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the PAT. + +We recommend using a service account with the least permissions necessary. Also when generating a new PAT, select the least scopes necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false ${{ github.token }}}] map[commit:{The commit SHA that was checked out } ref:{The branch, tag or SHA that was checked out }] {node20 map[] dist/index.js always() dist/index.js always() [] []} { }} from 'Unknown' +[CI Pipeline/storybook] โ˜ git clone 'https://github.com/actions/setup-node' # ref=v4 +[CI Pipeline/storybook] [DEBUG] cloning https://github.com/actions/setup-node to /Users/Vinod/.cache/act/actions-setup-node@v4 +[CI Pipeline/storybook] [DEBUG] Cloned https://github.com/actions/setup-node to /Users/Vinod/.cache/act/actions-setup-node@v4 +[CI Pipeline/storybook] [DEBUG] Checked out v4 +[CI Pipeline/storybook] [DEBUG] Read action &{Setup Node.js environment GitHub Setup a Node.js environment by adding problem matchers and optionally downloading and adding it to the PATH. map[always-auth:{Set always-auth in npmrc. false false} architecture:{Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default. false } cache:{Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm. false } cache-dependency-path:{Used to specify the path to a dependency file: package-lock.json, yarn.lock, etc. Supports wildcards or a list of file names for caching multiple dependencies. false } check-latest:{Set this option if you want the action to check for the latest available version that satisfies the version spec. false false} mirror:{Used to specify an alternative mirror to downlooad Node.js binaries from false } mirror-token:{The token used as Authorization header when fetching from the mirror false } node-version:{Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0. false } node-version-file:{File containing the version Spec of the version to use. Examples: package.json, .nvmrc, .node-version, .tool-versions. false } registry-url:{Optional registry to set up for auth. Will set the registry in a project level .npmrc and .yarnrc file, and set up auth to read in from env.NODE_AUTH_TOKEN. false } scope:{Optional scope for authenticating against scoped registries. Will fall back to the repository owner when using the GitHub Packages registry (https://npm.pkg.github.com/). false } token:{Used to pull node distributions from node-versions. Since there's a default, this is typically not supplied by the user. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting. false ${{ github.server_url == 'https://github.com' && github.token || '' }}}] map[cache-hit:{A boolean value to indicate if a cache was hit. } node-version:{The installed node version. }] {node20 map[] dist/setup/index.js always() dist/cache-save/index.js success() [] []} { }} from 'Unknown' +[CI Pipeline/storybook] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:0 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/checkout GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:storybook GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/storybook] [DEBUG] evaluating expression '' +[CI Pipeline/storybook] [DEBUG] expression '' evaluated to 'true' +[CI Pipeline/storybook] โญ Run Main Checkout code +[CI Pipeline/storybook] [DEBUG] About to run action &{Checkout Checkout a Git repository at a particular version map[clean:{Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching false true} fetch-depth:{Number of commits to fetch. 0 indicates all history for all branches and tags. false 1} fetch-tags:{Whether to fetch tags, even if fetch-depth > 0. false false} filter:{Partially clone against a given filter. Overrides sparse-checkout if set. + false } github-server-url:{The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com false } lfs:{Whether to download Git-LFS files false false} path:{Relative path under $GITHUB_WORKSPACE to place the repository false } persist-credentials:{Whether to configure the token or SSH key with the local git config false true} ref:{The branch, tag or SHA to checkout. When checking out the repository that triggered a workflow, this defaults to the reference or SHA for that event. Otherwise, uses the default branch. + false } repository:{Repository name with owner. For example, actions/checkout false ${{ github.repository }}} set-safe-directory:{Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory ` false true} show-progress:{Whether to show progress status output when fetching. false true} sparse-checkout:{Do a sparse checkout on given patterns. Each pattern should be separated with new lines. + false } sparse-checkout-cone-mode:{Specifies whether to use cone-mode when doing a sparse checkout. + false true} ssh-key:{SSH key used to fetch the repository. The SSH key is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the SSH key. + +We recommend using a service account with the least permissions necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false } ssh-known-hosts:{Known hosts in addition to the user and global host key database. The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, `ssh-keyscan github.com`. The public key for github.com is always implicitly added. + false } ssh-strict:{Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to configure additional hosts. + false true} ssh-user:{The user to use when connecting to the remote SSH host. By default 'git' is used. + false git} submodules:{Whether to checkout submodules: `true` to checkout submodules or `recursive` to recursively checkout submodules. + +When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are converted to HTTPS. + false false} token:{Personal access token (PAT) used to fetch the repository. The PAT is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the PAT. + +We recommend using a service account with the least permissions necessary. Also when generating a new PAT, select the least scopes necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false ${{ github.token }}}] map[commit:{The commit SHA that was checked out } ref:{The branch, tag or SHA that was checked out }] {node20 map[] dist/index.js always() dist/index.js always() [] []} { }} +[CI Pipeline/storybook] [DEBUG] expression '${{ github.repository }}' rewritten to 'format('{0}', github.repository)' +[CI Pipeline/storybook] [DEBUG] evaluating expression 'format('{0}', github.repository)' +[CI Pipeline/storybook] [DEBUG] expression 'format('{0}', github.repository)' evaluated to '%!t(string=CommunityRule/community-rule)' +[CI Pipeline/storybook] [DEBUG] expression '${{ github.token }}' rewritten to 'format('{0}', github.token)' +[CI Pipeline/storybook] [DEBUG] evaluating expression 'format('{0}', github.token)' +[CI Pipeline/storybook] [DEBUG] expression 'format('{0}', github.token)' evaluated to '%!t(string=***)' +[CI Pipeline/storybook] [DEBUG] type=remote-action actionDir=/Users/Vinod/.cache/act/actions-checkout@v4 actionPath= workdir=/workspace/CommunityRule/community-rule actionCacheDir=/Users/Vinod/.cache/act actionName=actions-checkout@v4 containerActionDir=/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/actions/actions-checkout@v4 +[CI Pipeline/storybook] [DEBUG] Removing /Users/Vinod/.cache/act/actions-checkout@v4/.gitignore before docker cp +[CI Pipeline/storybook] [DEBUG] /Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/actions/actions-checkout@v4 +[CI Pipeline/storybook] [DEBUG] Stripping prefix:/Users/Vinod/.cache/act/actions-checkout@v4/ src:/Users/Vinod/.cache/act/actions-checkout@v4/ +[CI Pipeline/storybook] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/actions/actions-checkout@v4/dist/index.js] +[CI Pipeline/storybook] | Cannot find: node in PATH +[CI Pipeline/storybook] โŒ Failure - Main Checkout code +[CI Pipeline/storybook] Cannot find: node in PATH +[CI Pipeline/storybook] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:1 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/setup-node GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:storybook GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/hostexecutor HOME:/Users/Vinod INPUT_CACHE:npm INPUT_NODE-VERSION:20 ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/storybook] [DEBUG] evaluating expression '' +[CI Pipeline/storybook] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/storybook] [DEBUG] Skipping step 'Setup Node.js' due to '' +[CI Pipeline/storybook] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:2 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:storybook GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/storybook] [DEBUG] evaluating expression '' +[CI Pipeline/storybook] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/storybook] [DEBUG] Skipping step 'Install dependencies' due to '' +[CI Pipeline/storybook] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:3 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:storybook GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/storybook] [DEBUG] evaluating expression '' +[CI Pipeline/storybook] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/storybook] [DEBUG] Skipping step 'Build Storybook' due to '' +[CI Pipeline/storybook] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:4 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:storybook GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/storybook] [DEBUG] evaluating expression '' +[CI Pipeline/storybook] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/storybook] [DEBUG] Skipping step 'Run Storybook tests' due to '' +[CI Pipeline/storybook] [DEBUG] skipping post step for 'Setup Node.js'; main step was skipped +[CI Pipeline/storybook] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50511/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:0 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/checkout GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_ENV:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/workflow/envs.txt GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:storybook GITHUB_OUTPUT:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/workflow/outputcmd.txt GITHUB_PATH:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/workflow/pathcmd.txt GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_STATE:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/workflow/statecmd.txt GITHUB_STEP_SUMMARY:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/workflow/SUMMARY.md GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/hostexecutor HOME:/Users/Vinod INPUT_CLEAN:true INPUT_FETCH-DEPTH:1 INPUT_FETCH-TAGS:false INPUT_FILTER: INPUT_GITHUB-SERVER-URL: INPUT_LFS:false INPUT_PATH: INPUT_PERSIST-CREDENTIALS:true INPUT_REF: INPUT_REPOSITORY:CommunityRule/community-rule INPUT_SET-SAFE-DIRECTORY:true INPUT_SHOW-PROGRESS:true INPUT_SPARSE-CHECKOUT: INPUT_SPARSE-CHECKOUT-CONE-MODE:true INPUT_SSH-KEY: INPUT_SSH-KNOWN-HOSTS: INPUT_SSH-STRICT:true INPUT_SSH-USER:git INPUT_SUBMODULES:false INPUT_TOKEN:*** ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/eaaa7b6f837dcf49/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/storybook] [DEBUG] evaluating expression 'always()' +[CI Pipeline/storybook] [DEBUG] expression 'always()' evaluated to 'true' +[CI Pipeline/storybook] โญ Run Post Checkout code +[CI Pipeline/storybook] [DEBUG] run post step for 'Checkout code' +[CI Pipeline/storybook] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/eaaa7b6f837dcf49/act/actions/actions-checkout@v4/dist/index.js] +[CI Pipeline/storybook] | Cannot find: node in PATH +[CI Pipeline/storybook] โŒ Failure - Post Checkout code +[CI Pipeline/storybook] Cleaning up services for job storybook +[CI Pipeline/storybook] Cleaning up container for job storybook +[CI Pipeline/storybook] ๐Ÿ Job failed +[CI Pipeline/lint] [DEBUG] evaluating expression 'success()' +[CI Pipeline/lint] [DEBUG] expression 'success()' evaluated to 'true' +[CI Pipeline/lint] โ˜ git clone 'https://github.com/actions/checkout' # ref=v4 +[CI Pipeline/lint] [DEBUG] cloning https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/lint] [DEBUG] Unable to pull refs/heads/v4: worktree contains unstaged changes +[CI Pipeline/lint] [DEBUG] Cloned https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/lint] [DEBUG] Checked out v4 +[CI Pipeline/lint] [DEBUG] Read action &{Checkout Checkout a Git repository at a particular version map[clean:{Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching false true} fetch-depth:{Number of commits to fetch. 0 indicates all history for all branches and tags. false 1} fetch-tags:{Whether to fetch tags, even if fetch-depth > 0. false false} filter:{Partially clone against a given filter. Overrides sparse-checkout if set. + false } github-server-url:{The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com false } lfs:{Whether to download Git-LFS files false false} path:{Relative path under $GITHUB_WORKSPACE to place the repository false } persist-credentials:{Whether to configure the token or SSH key with the local git config false true} ref:{The branch, tag or SHA to checkout. When checking out the repository that triggered a workflow, this defaults to the reference or SHA for that event. Otherwise, uses the default branch. + false } repository:{Repository name with owner. For example, actions/checkout false ${{ github.repository }}} set-safe-directory:{Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory ` false true} show-progress:{Whether to show progress status output when fetching. false true} sparse-checkout:{Do a sparse checkout on given patterns. Each pattern should be separated with new lines. + false } sparse-checkout-cone-mode:{Specifies whether to use cone-mode when doing a sparse checkout. + false true} ssh-key:{SSH key used to fetch the repository. The SSH key is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the SSH key. + +We recommend using a service account with the least permissions necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false } ssh-known-hosts:{Known hosts in addition to the user and global host key database. The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, `ssh-keyscan github.com`. The public key for github.com is always implicitly added. + false } ssh-strict:{Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to configure additional hosts. + false true} ssh-user:{The user to use when connecting to the remote SSH host. By default 'git' is used. + false git} submodules:{Whether to checkout submodules: `true` to checkout submodules or `recursive` to recursively checkout submodules. + +When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are converted to HTTPS. + false false} token:{Personal access token (PAT) used to fetch the repository. The PAT is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the PAT. + +We recommend using a service account with the least permissions necessary. Also when generating a new PAT, select the least scopes necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false ${{ github.token }}}] map[commit:{The commit SHA that was checked out } ref:{The branch, tag or SHA that was checked out }] {node20 map[] dist/index.js always() dist/index.js always() [] []} { }} from 'Unknown' +[CI Pipeline/lint] context canceled +[CI Pipeline/lint] [DEBUG] skipping post step for 'Setup Node.js'; step was not executed +[CI Pipeline/lint] [DEBUG] skipping post step for 'Checkout code'; step was not executed +[CI Pipeline/lint] Cleaning up services for job lint +[CI Pipeline/lint] Cleaning up container for job lint +[CI Pipeline/lint] ๐Ÿ Job succeeded +[CI Pipeline/build] [DEBUG] evaluating expression 'success()' +[CI Pipeline/build] [DEBUG] expression 'success()' evaluated to 'true' +[CI Pipeline/build] โ˜ git clone 'https://github.com/actions/checkout' # ref=v4 +[CI Pipeline/build] [DEBUG] cloning https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/build] [DEBUG] Cloned https://github.com/actions/checkout to /Users/Vinod/.cache/act/actions-checkout@v4 +[CI Pipeline/build] [DEBUG] Checked out v4 +[CI Pipeline/build] [DEBUG] Read action &{Checkout Checkout a Git repository at a particular version map[clean:{Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching false true} fetch-depth:{Number of commits to fetch. 0 indicates all history for all branches and tags. false 1} fetch-tags:{Whether to fetch tags, even if fetch-depth > 0. false false} filter:{Partially clone against a given filter. Overrides sparse-checkout if set. + false } github-server-url:{The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com false } lfs:{Whether to download Git-LFS files false false} path:{Relative path under $GITHUB_WORKSPACE to place the repository false } persist-credentials:{Whether to configure the token or SSH key with the local git config false true} ref:{The branch, tag or SHA to checkout. When checking out the repository that triggered a workflow, this defaults to the reference or SHA for that event. Otherwise, uses the default branch. + false } repository:{Repository name with owner. For example, actions/checkout false ${{ github.repository }}} set-safe-directory:{Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory ` false true} show-progress:{Whether to show progress status output when fetching. false true} sparse-checkout:{Do a sparse checkout on given patterns. Each pattern should be separated with new lines. + false } sparse-checkout-cone-mode:{Specifies whether to use cone-mode when doing a sparse checkout. + false true} ssh-key:{SSH key used to fetch the repository. The SSH key is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the SSH key. + +We recommend using a service account with the least permissions necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false } ssh-known-hosts:{Known hosts in addition to the user and global host key database. The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, `ssh-keyscan github.com`. The public key for github.com is always implicitly added. + false } ssh-strict:{Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to configure additional hosts. + false true} ssh-user:{The user to use when connecting to the remote SSH host. By default 'git' is used. + false git} submodules:{Whether to checkout submodules: `true` to checkout submodules or `recursive` to recursively checkout submodules. + +When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are converted to HTTPS. + false false} token:{Personal access token (PAT) used to fetch the repository. The PAT is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the PAT. + +We recommend using a service account with the least permissions necessary. Also when generating a new PAT, select the least scopes necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false ${{ github.token }}}] map[commit:{The commit SHA that was checked out } ref:{The branch, tag or SHA that was checked out }] {node20 map[] dist/index.js always() dist/index.js always() [] []} { }} from 'Unknown' +[CI Pipeline/build] โ˜ git clone 'https://github.com/actions/setup-node' # ref=v4 +[CI Pipeline/build] [DEBUG] cloning https://github.com/actions/setup-node to /Users/Vinod/.cache/act/actions-setup-node@v4 +[CI Pipeline/build] [DEBUG] Cloned https://github.com/actions/setup-node to /Users/Vinod/.cache/act/actions-setup-node@v4 +[CI Pipeline/build] [DEBUG] Checked out v4 +[CI Pipeline/build] [DEBUG] Read action &{Setup Node.js environment GitHub Setup a Node.js environment by adding problem matchers and optionally downloading and adding it to the PATH. map[always-auth:{Set always-auth in npmrc. false false} architecture:{Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default. false } cache:{Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm. false } cache-dependency-path:{Used to specify the path to a dependency file: package-lock.json, yarn.lock, etc. Supports wildcards or a list of file names for caching multiple dependencies. false } check-latest:{Set this option if you want the action to check for the latest available version that satisfies the version spec. false false} mirror:{Used to specify an alternative mirror to downlooad Node.js binaries from false } mirror-token:{The token used as Authorization header when fetching from the mirror false } node-version:{Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0. false } node-version-file:{File containing the version Spec of the version to use. Examples: package.json, .nvmrc, .node-version, .tool-versions. false } registry-url:{Optional registry to set up for auth. Will set the registry in a project level .npmrc and .yarnrc file, and set up auth to read in from env.NODE_AUTH_TOKEN. false } scope:{Optional scope for authenticating against scoped registries. Will fall back to the repository owner when using the GitHub Packages registry (https://npm.pkg.github.com/). false } token:{Used to pull node distributions from node-versions. Since there's a default, this is typically not supplied by the user. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting. false ${{ github.server_url == 'https://github.com' && github.token || '' }}}] map[cache-hit:{A boolean value to indicate if a cache was hit. } node-version:{The installed node version. }] {node20 map[] dist/setup/index.js always() dist/cache-save/index.js success() [] []} { }} from 'Unknown' +[CI Pipeline/build] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50541/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:0 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/checkout GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:build GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/bae0e73dbed73bd8/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/bae0e73dbed73bd8/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/build] [DEBUG] evaluating expression '' +[CI Pipeline/build] [DEBUG] expression '' evaluated to 'true' +[CI Pipeline/build] โญ Run Main Checkout code +[CI Pipeline/build] [DEBUG] About to run action &{Checkout Checkout a Git repository at a particular version map[clean:{Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching false true} fetch-depth:{Number of commits to fetch. 0 indicates all history for all branches and tags. false 1} fetch-tags:{Whether to fetch tags, even if fetch-depth > 0. false false} filter:{Partially clone against a given filter. Overrides sparse-checkout if set. + false } github-server-url:{The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com false } lfs:{Whether to download Git-LFS files false false} path:{Relative path under $GITHUB_WORKSPACE to place the repository false } persist-credentials:{Whether to configure the token or SSH key with the local git config false true} ref:{The branch, tag or SHA to checkout. When checking out the repository that triggered a workflow, this defaults to the reference or SHA for that event. Otherwise, uses the default branch. + false } repository:{Repository name with owner. For example, actions/checkout false ${{ github.repository }}} set-safe-directory:{Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory ` false true} show-progress:{Whether to show progress status output when fetching. false true} sparse-checkout:{Do a sparse checkout on given patterns. Each pattern should be separated with new lines. + false } sparse-checkout-cone-mode:{Specifies whether to use cone-mode when doing a sparse checkout. + false true} ssh-key:{SSH key used to fetch the repository. The SSH key is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the SSH key. + +We recommend using a service account with the least permissions necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false } ssh-known-hosts:{Known hosts in addition to the user and global host key database. The public SSH keys for a host may be obtained using the utility `ssh-keyscan`. For example, `ssh-keyscan github.com`. The public key for github.com is always implicitly added. + false } ssh-strict:{Whether to perform strict host key checking. When true, adds the options `StrictHostKeyChecking=yes` and `CheckHostIP=no` to the SSH command line. Use the input `ssh-known-hosts` to configure additional hosts. + false true} ssh-user:{The user to use when connecting to the remote SSH host. By default 'git' is used. + false git} submodules:{Whether to checkout submodules: `true` to checkout submodules or `recursive` to recursively checkout submodules. + +When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are converted to HTTPS. + false false} token:{Personal access token (PAT) used to fetch the repository. The PAT is configured with the local git config, which enables your scripts to run authenticated git commands. The post-job step removes the PAT. + +We recommend using a service account with the least permissions necessary. Also when generating a new PAT, select the least scopes necessary. + +[Learn more about creating and using encrypted secrets](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets) + false ${{ github.token }}}] map[commit:{The commit SHA that was checked out } ref:{The branch, tag or SHA that was checked out }] {node20 map[] dist/index.js always() dist/index.js always() [] []} { }} +[CI Pipeline/build] [DEBUG] expression '${{ github.repository }}' rewritten to 'format('{0}', github.repository)' +[CI Pipeline/build] [DEBUG] evaluating expression 'format('{0}', github.repository)' +[CI Pipeline/build] [DEBUG] expression 'format('{0}', github.repository)' evaluated to '%!t(string=CommunityRule/community-rule)' +[CI Pipeline/build] [DEBUG] expression '${{ github.token }}' rewritten to 'format('{0}', github.token)' +[CI Pipeline/build] [DEBUG] evaluating expression 'format('{0}', github.token)' +[CI Pipeline/build] [DEBUG] expression 'format('{0}', github.token)' evaluated to '%!t(string=***)' +[CI Pipeline/build] [DEBUG] type=remote-action actionDir=/Users/Vinod/.cache/act/actions-checkout@v4 actionPath= workdir=/workspace/CommunityRule/community-rule actionCacheDir=/Users/Vinod/.cache/act actionName=actions-checkout@v4 containerActionDir=/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/actions/actions-checkout@v4 +[CI Pipeline/build] [DEBUG] Removing /Users/Vinod/.cache/act/actions-checkout@v4/.gitignore before docker cp +[CI Pipeline/build] [DEBUG] /Users/Vinod/.cache/act/bae0e73dbed73bd8/act/actions/actions-checkout@v4 +[CI Pipeline/build] [DEBUG] Stripping prefix:/Users/Vinod/.cache/act/actions-checkout@v4/ src:/Users/Vinod/.cache/act/actions-checkout@v4/ +[CI Pipeline/build] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/bae0e73dbed73bd8/act/actions/actions-checkout@v4/dist/index.js] +[CI Pipeline/build] | Cannot find: node in PATH +[CI Pipeline/build] โŒ Failure - Main Checkout code +[CI Pipeline/build] Cannot find: node in PATH +[CI Pipeline/build] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50541/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:1 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/setup-node GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:build GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/bae0e73dbed73bd8/hostexecutor HOME:/Users/Vinod INPUT_CACHE:npm INPUT_NODE-VERSION:20 ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/bae0e73dbed73bd8/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/build] [DEBUG] evaluating expression '' +[CI Pipeline/build] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/build] [DEBUG] Skipping step 'Setup Node.js' due to '' +[CI Pipeline/build] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50541/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:2 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:build GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/bae0e73dbed73bd8/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/bae0e73dbed73bd8/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/build] [DEBUG] evaluating expression '' +[CI Pipeline/build] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/build] [DEBUG] Skipping step 'Install dependencies' due to '' +[CI Pipeline/build] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50541/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:3 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:build GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/bae0e73dbed73bd8/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/bae0e73dbed73bd8/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/build] [DEBUG] evaluating expression '' +[CI Pipeline/build] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/build] [DEBUG] Skipping step 'Build application' due to '' +[CI Pipeline/build] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50541/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:4 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF: GITHUB_ACTION_REPOSITORY: GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:build GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/bae0e73dbed73bd8/hostexecutor HOME:/Users/Vinod ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/bae0e73dbed73bd8/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/build] [DEBUG] evaluating expression '' +[CI Pipeline/build] [DEBUG] expression '' evaluated to 'false' +[CI Pipeline/build] [DEBUG] Skipping step 'Build Storybook' due to '' +[CI Pipeline/build] [DEBUG] skipping post step for 'Setup Node.js'; main step was skipped +[CI Pipeline/build] [DEBUG] setupEnv => map[ACT:true ACTIONS_CACHE_URL:http://192.168.1.3:50541/ ACTIONS_RUNTIME_TOKEN:*** ACTIONS_RUNTIME_URL:https://git.medlab.host/api/actions_pipeline/ CI:true GITEA_ACTIONS:true GITEA_ACTIONS_RUNNER_VERSION:v0.2.6 GITHUB_ACTION:0 GITHUB_ACTIONS:true GITHUB_ACTION_PATH: GITHUB_ACTION_REF:v4 GITHUB_ACTION_REPOSITORY:actions/checkout GITHUB_ACTOR:an.di GITHUB_API_URL:https://git.medlab.host/api/v1 GITHUB_BASE_REF: GITHUB_ENV:/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/workflow/envs.txt GITHUB_EVENT_NAME:push GITHUB_EVENT_PATH:/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/workflow/event.json GITHUB_GRAPHQL_URL: GITHUB_HEAD_REF: GITHUB_JOB:build GITHUB_OUTPUT:/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/workflow/outputcmd.txt GITHUB_PATH:/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/workflow/pathcmd.txt GITHUB_REF:refs/heads/adilallo/enhancement/TestingFramework GITHUB_REF_NAME:adilallo/enhancement/TestingFramework GITHUB_REF_TYPE:branch GITHUB_REPOSITORY:CommunityRule/community-rule GITHUB_REPOSITORY_OWNER:CommunityRule GITHUB_RETENTION_DAYS: GITHUB_RUN_ID:13 GITHUB_RUN_NUMBER:1 GITHUB_SERVER_URL:https://git.medlab.host GITHUB_SHA:dec2757f88b843da25faf219cb03491d3ef8cd4d GITHUB_STATE:/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/workflow/statecmd.txt GITHUB_STEP_SUMMARY:/Users/Vinod/.cache/act/bae0e73dbed73bd8/act/workflow/SUMMARY.md GITHUB_TOKEN:*** GITHUB_WORKFLOW:CI Pipeline GITHUB_WORKSPACE:/Users/Vinod/.cache/act/bae0e73dbed73bd8/hostexecutor HOME:/Users/Vinod INPUT_CLEAN:true INPUT_FETCH-DEPTH:1 INPUT_FETCH-TAGS:false INPUT_FILTER: INPUT_GITHUB-SERVER-URL: INPUT_LFS:false INPUT_PATH: INPUT_PERSIST-CREDENTIALS:true INPUT_REF: INPUT_REPOSITORY:CommunityRule/community-rule INPUT_SET-SAFE-DIRECTORY:true INPUT_SHOW-PROGRESS:true INPUT_SPARSE-CHECKOUT: INPUT_SPARSE-CHECKOUT-CONE-MODE:true INPUT_SSH-KEY: INPUT_SSH-KNOWN-HOSTS: INPUT_SSH-STRICT:true INPUT_SSH-USER:git INPUT_SUBMODULES:false INPUT_TOKEN:*** ImageOS:macoslatest LOGNAME:Vinod PATH:/usr/bin:/bin:/usr/sbin:/sbin RUNNER_ARCH:amd64 RUNNER_OS:macOS RUNNER_PERFLOG:/dev/null RUNNER_TEMP:/Users/Vinod/.cache/act/bae0e73dbed73bd8/tmp RUNNER_TOOL_CACHE:/Users/Vinod/.cache/act/tool_cache RUNNER_TRACKING_ID: SHELL:/bin/bash SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.TR6IO7q3CL/Listeners TMPDIR:/var/folders/zh/1tz9wdyd7zd5qr_x789vr2s00000gn/T/ USER:Vinod XPC_FLAGS:0x0 XPC_SERVICE_NAME:com.gitea.act-runner] +[CI Pipeline/build] [DEBUG] evaluating expression 'always()' +[CI Pipeline/build] [DEBUG] expression 'always()' evaluated to 'true' +[CI Pipeline/build] โญ Run Post Checkout code +[CI Pipeline/build] [DEBUG] run post step for 'Checkout code' +[CI Pipeline/build] [DEBUG] executing remote job container: [node /Users/Vinod/.cache/act/bae0e73dbed73bd8/act/actions/actions-checkout@v4/dist/index.js] +[CI Pipeline/build] | Cannot find: node in PATH +[CI Pipeline/build] โŒ Failure - Post Checkout code +[CI Pipeline/build] Cleaning up services for job build +[CI Pipeline/build] Cleaning up container for job build +[CI Pipeline/build] ๐Ÿ Job failed diff --git a/scripts/performance-monitor.js b/scripts/performance-monitor.js new file mode 100644 index 0000000..72738bd --- /dev/null +++ b/scripts/performance-monitor.js @@ -0,0 +1,387 @@ +#!/usr/bin/env node + +/** + * Performance Monitoring Script + * + * This script provides comprehensive performance monitoring capabilities + * for the Community Rule application. + */ + +const { spawn } = require("child_process"); +const fs = require("fs"); +const path = require("path"); + +// Performance budgets +const PERFORMANCE_BUDGETS = { + page_load_time: 3000, + first_contentful_paint: 2000, + largest_contentful_paint: 2500, + first_input_delay: 100, + dns_lookup: 100, + tcp_connection: 200, + ttfb: 600, + dom_content_loaded: 1500, + full_load: 3000, + component_render_time: 500, + interaction_time: 100, + scroll_performance: 50, + network_request_duration: 1000, + memory_usage_mb: 50, +}; + +// Baseline metrics for regression detection +const BASELINE_METRICS = { + page_load_time: 2000, + first_contentful_paint: 1500, + largest_contentful_paint: 2000, + first_input_delay: 50, + dns_lookup: 50, + tcp_connection: 100, + ttfb: 400, + dom_content_loaded: 1000, + full_load: 2000, + component_render_time: 300, + interaction_time: 50, + scroll_performance: 30, + network_request_duration: 500, + memory_usage_mb: 30, +}; + +class PerformanceMonitorScript { + constructor() { + this.metrics = new Map(); + this.regressions = []; + this.warnings = []; + } + + /** + * Run Lighthouse CI performance tests + */ + async runLighthouseCI() { + console.log("๐Ÿš€ Running Lighthouse CI performance tests..."); + + return new Promise((resolve, reject) => { + const lhci = spawn("npx", ["lhci", "autorun"], { + stdio: "pipe", + shell: true, + }); + + let output = ""; + let errorOutput = ""; + + lhci.stdout.on("data", (data) => { + output += data.toString(); + console.log(data.toString()); + }); + + lhci.stderr.on("data", (data) => { + errorOutput += data.toString(); + console.error(data.toString()); + }); + + lhci.on("close", (code) => { + if (code === 0) { + console.log("โœ… Lighthouse CI tests completed successfully"); + this.analyzeLighthouseResults(output); + resolve(output); + } else { + console.error("โŒ Lighthouse CI tests failed"); + reject( + new Error(`Lighthouse CI failed with code ${code}: ${errorOutput}`) + ); + } + }); + }); + } + + /** + * Run Playwright performance tests + */ + async runPlaywrightPerformanceTests() { + console.log("๐ŸŽญ Running Playwright performance tests..."); + + return new Promise((resolve, reject) => { + const playwright = spawn( + "npx", + [ + "playwright", + "test", + "tests/e2e/performance.spec.ts", + "--reporter=json", + ], + { + stdio: "pipe", + shell: true, + } + ); + + let output = ""; + let errorOutput = ""; + + playwright.stdout.on("data", (data) => { + output += data.toString(); + }); + + playwright.stderr.on("data", (data) => { + errorOutput += data.toString(); + }); + + playwright.on("close", (code) => { + if (code === 0) { + console.log("โœ… Playwright performance tests completed successfully"); + this.analyzePlaywrightResults(output); + resolve(output); + } else { + console.error("โŒ Playwright performance tests failed"); + reject( + new Error( + `Playwright tests failed with code ${code}: ${errorOutput}` + ) + ); + } + }); + }); + } + + /** + * Analyze Lighthouse CI results + */ + analyzeLighthouseResults(output) { + console.log("๐Ÿ“Š Analyzing Lighthouse CI results..."); + + // Parse Lighthouse results + const lines = output.split("\n"); + let currentMetric = null; + + for (const line of lines) { + if (line.includes("Performance")) { + const scoreMatch = line.match(/(\d+)/); + if (scoreMatch) { + const score = parseInt(scoreMatch[1]); + this.recordMetric("lighthouse_performance_score", score); + + if (score < 90) { + this.warnings.push( + `Performance score below threshold: ${score}/100` + ); + } + } + } + + if (line.includes("First Contentful Paint")) { + const timeMatch = line.match(/(\d+(?:\.\d+)?)\s*ms/); + if (timeMatch) { + const time = parseFloat(timeMatch[1]); + this.recordMetric("first_contentful_paint", time); + + if (time > PERFORMANCE_BUDGETS.first_contentful_paint) { + this.warnings.push( + `First Contentful Paint exceeded budget: ${time}ms` + ); + } + } + } + + if (line.includes("Largest Contentful Paint")) { + const timeMatch = line.match(/(\d+(?:\.\d+)?)\s*ms/); + if (timeMatch) { + const time = parseFloat(timeMatch[1]); + this.recordMetric("largest_contentful_paint", time); + + if (time > PERFORMANCE_BUDGETS.largest_contentful_paint) { + this.warnings.push( + `Largest Contentful Paint exceeded budget: ${time}ms` + ); + } + } + } + + if (line.includes("Total Blocking Time")) { + const timeMatch = line.match(/(\d+(?:\.\d+)?)\s*ms/); + if (timeMatch) { + const time = parseFloat(timeMatch[1]); + this.recordMetric("total_blocking_time", time); + + if (time > 300) { + this.warnings.push( + `Total Blocking Time exceeded budget: ${time}ms` + ); + } + } + } + + if (line.includes("Cumulative Layout Shift")) { + const shiftMatch = line.match(/(\d+(?:\.\d+)?)/); + if (shiftMatch) { + const shift = parseFloat(shiftMatch[1]); + this.recordMetric("cumulative_layout_shift", shift); + + if (shift > 0.1) { + this.warnings.push( + `Cumulative Layout Shift exceeded budget: ${shift}` + ); + } + } + } + } + } + + /** + * Analyze Playwright test results + */ + analyzePlaywrightResults(output) { + console.log("๐Ÿ“Š Analyzing Playwright test results..."); + + try { + const results = JSON.parse(output); + + for (const result of results) { + if (result.status === "failed") { + this.warnings.push(`Test failed: ${result.title}`); + } + } + } catch (error) { + console.warn("Could not parse Playwright results as JSON"); + } + } + + /** + * Record a performance metric + */ + recordMetric(name, value) { + if (!this.metrics.has(name)) { + this.metrics.set(name, []); + } + this.metrics.get(name).push({ + value, + timestamp: Date.now(), + }); + + // Check against baseline for regression detection + const baseline = BASELINE_METRICS[name]; + if (baseline) { + const regressionThreshold = baseline * 1.2; // 20% regression threshold + if (value > regressionThreshold) { + this.regressions.push({ + metric: name, + current: value, + baseline, + regression: (((value - baseline) / baseline) * 100).toFixed(1) + "%", + }); + } + } + } + + /** + * Generate performance report + */ + generateReport() { + console.log("\n๐Ÿ“ˆ Performance Monitoring Report"); + console.log("================================\n"); + + // Summary + console.log("๐Ÿ“Š Summary:"); + console.log(`- Total metrics recorded: ${this.metrics.size}`); + console.log( + `- Performance regressions detected: ${this.regressions.length}` + ); + console.log(`- Warnings: ${this.warnings.length}\n`); + + // Performance regressions + if (this.regressions.length > 0) { + console.log("๐Ÿšจ Performance Regressions:"); + for (const regression of this.regressions) { + console.log( + ` - ${regression.metric}: ${regression.current} (baseline: ${regression.baseline}, regression: ${regression.regression})` + ); + } + console.log(""); + } + + // Warnings + if (this.warnings.length > 0) { + console.log("โš ๏ธ Warnings:"); + for (const warning of this.warnings) { + console.log(` - ${warning}`); + } + console.log(""); + } + + // Metrics summary + console.log("๐Ÿ“‹ Metrics Summary:"); + for (const [name, values] of this.metrics) { + const latest = values[values.length - 1]; + const average = + values.reduce((sum, v) => sum + v.value, 0) / values.length; + const budget = PERFORMANCE_BUDGETS[name]; + + console.log(` - ${name}:`); + console.log(` Latest: ${latest.value}`); + console.log(` Average: ${average.toFixed(2)}`); + if (budget) { + const status = latest.value <= budget ? "โœ…" : "โŒ"; + console.log(` Budget: ${budget} ${status}`); + } + } + + // Save report to file + const report = { + timestamp: new Date().toISOString(), + summary: { + totalMetrics: this.metrics.size, + regressions: this.regressions.length, + warnings: this.warnings.length, + }, + regressions: this.regressions, + warnings: this.warnings, + metrics: Object.fromEntries(this.metrics), + }; + + const reportPath = path.join(__dirname, "../performance-report.json"); + fs.writeFileSync(reportPath, JSON.stringify(report, null, 2)); + console.log(`\n๐Ÿ“„ Report saved to: ${reportPath}`); + + return report; + } + + /** + * Run all performance monitoring + */ + async run() { + console.log("๐Ÿ” Starting Performance Monitoring...\n"); + + try { + // Run Lighthouse CI tests + await this.runLighthouseCI(); + + // Run Playwright performance tests + await this.runPlaywrightPerformanceTests(); + + // Generate and display report + const report = this.generateReport(); + + // Exit with appropriate code + if (this.regressions.length > 0) { + console.log("โŒ Performance regressions detected!"); + process.exit(1); + } else if (this.warnings.length > 0) { + console.log("โš ๏ธ Performance warnings detected."); + process.exit(0); + } else { + console.log("โœ… All performance checks passed!"); + process.exit(0); + } + } catch (error) { + console.error("โŒ Performance monitoring failed:", error.message); + process.exit(1); + } + } +} + +// Run the performance monitor if this script is executed directly +if (require.main === module) { + const monitor = new PerformanceMonitorScript(); + monitor.run(); +} + +module.exports = PerformanceMonitorScript; diff --git a/scripts/seed-snapshots.sh b/scripts/seed-snapshots.sh new file mode 100755 index 0000000..ef5d519 --- /dev/null +++ b/scripts/seed-snapshots.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# Script to seed visual regression snapshots using Playwright Docker container +# This ensures the snapshots are generated in the same environment as CI + +set -e + +echo "๐Ÿš€ Seeding visual regression snapshots using Playwright Docker container..." + +# Check if Docker is available +if ! command -v docker &> /dev/null; then + echo "โŒ Docker is not installed or not available in PATH" + exit 1 +fi + +# Run the Playwright container and generate snapshots +docker run --rm -it \ + -v "$(pwd):/work" \ + -w /work \ + mcr.microsoft.com/playwright:v1.54.2-jammy \ + bash -c " + echo '๐Ÿ“ฆ Installing dependencies...' + npm ci + + echo '๐ŸŽญ Installing Playwright browsers...' + npx playwright install --with-deps + + echo '๐Ÿ”จ Building application...' + npm run build + + echo '๐ŸŒ Starting preview server...' + npm run preview & + sleep 10 + + echo '๐Ÿ“ธ Generating snapshots...' + PLAYWRIGHT_UPDATE_SNAPSHOTS=1 npx playwright test tests/e2e/visual-regression.spec.ts --project=chromium + + echo 'โœ… Snapshots generated successfully!' + " + +echo "๐ŸŽ‰ Snapshot seeding completed!" +echo "๐Ÿ“ Check the generated snapshots in: tests/e2e/visual-regression.spec.ts-snapshots/" +echo "๐Ÿ’ก Don't forget to commit the snapshot files to your repository" diff --git a/scripts/test-lhci.js b/scripts/test-lhci.js new file mode 100644 index 0000000..e8033f2 --- /dev/null +++ b/scripts/test-lhci.js @@ -0,0 +1,62 @@ +#!/usr/bin/env node + +/** + * Simple test script to verify LHCI configuration + * This script validates the configuration without running actual tests + */ + +const fs = require('fs'); +const path = require('path'); + +console.log('๐Ÿ” Testing LHCI Configuration...\n'); + +// Check if .lighthouserc.json exists +const configPath = path.join(process.cwd(), '.lighthouserc.json'); +if (fs.existsSync(configPath)) { + console.log('โœ… .lighthouserc.json found'); + + try { + const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); + console.log('โœ… Configuration is valid JSON'); + + if (config.ci && config.ci.collect && config.ci.assert) { + console.log('โœ… Configuration has required sections (collect, assert)'); + console.log(`โœ… Testing ${config.ci.collect.numberOfRuns} runs`); + console.log(`โœ… URL: ${config.ci.collect.url[0]}`); + } else { + console.log('โŒ Configuration missing required sections'); + } + } catch (error) { + console.log('โŒ Configuration is not valid JSON:', error.message); + } +} else { + console.log('โŒ .lighthouserc.json not found'); +} + +// Check if @lhci/cli is installed +try { + const { execSync } = require('child_process'); + execSync('npx lhci --version', { stdio: 'pipe' }); + console.log('โœ… @lhci/cli package is installed and working'); +} catch (error) { + console.log('โŒ @lhci/cli package is not working:', error.message); +} + +// Check package.json scripts +const packagePath = path.join(process.cwd(), 'package.json'); +if (fs.existsSync(packagePath)) { + try { + const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8')); + if (packageJson.scripts && packageJson.scripts.lhci) { + console.log('โœ… LHCI script found in package.json'); + } else { + console.log('โŒ LHCI script not found in package.json'); + } + } catch (error) { + console.log('โŒ Error reading package.json:', error.message); + } +} + +console.log('\n๐ŸŽ‰ LHCI Configuration Test Complete!'); +console.log('Note: Actual LHCI tests may fail locally due to Node.js architecture issues on macOS.'); +console.log('The CI environment should work correctly with the provided configuration.'); diff --git a/start-runner.sh b/start-runner.sh new file mode 100755 index 0000000..e669821 --- /dev/null +++ b/start-runner.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +echo "๐Ÿš€ Starting Gitea Actions Runner..." + +# Check if runner is already running +if pgrep -f "act_runner daemon" > /dev/null; then + echo "โš ๏ธ Runner is already running!" + echo "To stop it, run: ./stop-runner.sh" + exit 1 +fi + +# Start the runner in the background +./act_runner daemon --config config.yaml & +RUNNER_PID=$! + +# Save PID to file for easy stopping +echo $RUNNER_PID > .runner.pid + +echo "โœ… Runner started with PID: $RUNNER_PID" +echo "๐Ÿ“ Logs will be written to: runner.log" +echo "" +echo "To stop the runner, run: ./stop-runner.sh" +echo "To check status, run: ./status-runner.sh" diff --git a/status-runner.sh b/status-runner.sh new file mode 100755 index 0000000..fbec71b --- /dev/null +++ b/status-runner.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +echo "๐Ÿ“Š Gitea Actions Runner Status" +echo "==============================" + +# Check if runner is running +if pgrep -f "act_runner daemon" > /dev/null; then + RUNNER_PID=$(pgrep -f "act_runner daemon") + echo "โœ… Runner is RUNNING (PID: $RUNNER_PID)" + echo "" + echo "๐Ÿ“ Recent logs:" + if [ -f runner.log ]; then + tail -5 runner.log + else + echo "No log file found" + fi + echo "" + echo "To stop the runner: ./stop-runner.sh" +else + echo "โŒ Runner is NOT RUNNING" + echo "" + echo "To start the runner: ./start-runner.sh" +fi + +echo "" +echo "๐Ÿ”— Gitea Actions URL:" +echo "https://git.medlab.host/CommunityRule/community-rule/actions" diff --git a/stop-runner.sh b/stop-runner.sh new file mode 100755 index 0000000..c13468d --- /dev/null +++ b/stop-runner.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +echo "๐Ÿ›‘ Stopping Gitea Actions Runner..." + +# Check if PID file exists +if [ -f .runner.pid ]; then + RUNNER_PID=$(cat .runner.pid) + + # Check if process is still running + if ps -p $RUNNER_PID > /dev/null; then + echo "๐Ÿ”„ Stopping runner with PID: $RUNNER_PID" + kill $RUNNER_PID + + # Wait a moment for graceful shutdown + sleep 2 + + # Force kill if still running + if ps -p $RUNNER_PID > /dev/null; then + echo "โšก Force stopping runner..." + kill -9 $RUNNER_PID + fi + + echo "โœ… Runner stopped successfully" + else + echo "โš ๏ธ Runner process not found (PID: $RUNNER_PID)" + fi + + # Clean up PID file + rm -f .runner.pid +else + echo "๐Ÿ” No PID file found, checking for any running runners..." + pkill -f "act_runner daemon" + echo "โœ… Any running runners have been stopped" +fi diff --git a/stories/Button.visual.stories.js b/stories/Button.visual.stories.js new file mode 100644 index 0000000..4860075 --- /dev/null +++ b/stories/Button.visual.stories.js @@ -0,0 +1,353 @@ +import Button from "../app/components/Button.js"; +import { within, userEvent } from "@storybook/test"; + +export default { + title: "Components/Button/Visual Regression", + component: Button, + parameters: { + // Chromatic configuration for visual testing + chromatic: { + viewports: [320, 640, 1024, 1280], + delay: 200, + modes: { + light: {}, + dark: { + colorScheme: "dark", + }, + }, + }, + }, + argTypes: { + size: { + control: { type: "select" }, + options: ["xsmall", "small", "medium", "large", "xlarge"], + }, + variant: { + control: { type: "select" }, + options: ["default", "home"], + }, + disabled: { + control: { type: "boolean" }, + }, + }, +}; + +// Default button states +export const Default = { + args: { + children: "Default Button", + }, + parameters: { + docs: { + description: { + story: "Default button state for visual regression testing.", + }, + }, + }, +}; + +export const Hover = { + args: { + children: "Hover Button", + }, + parameters: { + docs: { + description: { + story: "Button in hover state for visual regression testing.", + }, + }, + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const button = canvas.getByRole("button"); + await userEvent.hover(button); + await new Promise((resolve) => setTimeout(resolve, 100)); + }, +}; + +export const Focus = { + args: { + children: "Focus Button", + }, + parameters: { + docs: { + description: { + story: "Button in focus state for visual regression testing.", + }, + }, + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const button = canvas.getByRole("button"); + button.focus(); + await new Promise((resolve) => setTimeout(resolve, 100)); + }, +}; + +export const Active = { + args: { + children: "Active Button", + }, + parameters: { + docs: { + description: { + story: "Button in active/pressed state for visual regression testing.", + }, + }, + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const button = canvas.getByRole("button"); + await userEvent.click(button); + await new Promise((resolve) => setTimeout(resolve, 100)); + }, +}; + +export const Disabled = { + args: { + children: "Disabled Button", + disabled: true, + }, + parameters: { + docs: { + description: { + story: "Disabled button state for visual regression testing.", + }, + }, + }, +}; + +// Size variants +export const XSmall = { + args: { + children: "XSmall Button", + size: "xsmall", + }, + parameters: { + docs: { + description: { + story: "Extra small button size for visual regression testing.", + }, + }, + }, +}; + +export const Small = { + args: { + children: "Small Button", + size: "small", + }, + parameters: { + docs: { + description: { + story: "Small button size for visual regression testing.", + }, + }, + }, +}; + +export const Medium = { + args: { + children: "Medium Button", + size: "medium", + }, + parameters: { + docs: { + description: { + story: "Medium button size for visual regression testing.", + }, + }, + }, +}; + +export const Large = { + args: { + children: "Large Button", + size: "large", + }, + parameters: { + docs: { + description: { + story: "Large button size for visual regression testing.", + }, + }, + }, +}; + +export const XLarge = { + args: { + children: "XLarge Button", + size: "xlarge", + }, + parameters: { + docs: { + description: { + story: "Extra large button size for visual regression testing.", + }, + }, + }, +}; + +// Variant styles +export const HomeVariant = { + args: { + children: "Home Button", + variant: "home", + }, + parameters: { + docs: { + description: { + story: "Home variant button for visual regression testing.", + }, + }, + }, +}; + +// Button with icon/content +export const WithIcon = { + args: { + children: ( + <> + Button with Icon + + + + + ), + }, + parameters: { + docs: { + description: { + story: "Button with icon for visual regression testing.", + }, + }, + }, +}; + +export const LongText = { + args: { + children: + "This is a button with very long text content that might wrap or overflow", + }, + parameters: { + docs: { + description: { + story: "Button with long text for visual regression testing.", + }, + }, + }, +}; + +// Button grid for comparison +export const SizeComparison = { + render: () => ( +
+
+ + + + + +
+
+ ), + parameters: { + docs: { + description: { + story: "All button sizes for comparison and visual regression testing.", + }, + }, + }, +}; + +export const StateComparison = { + render: () => ( +
+
+ + +
+
+ + +
+
+ ), + parameters: { + docs: { + description: { + story: "Button states for comparison and visual regression testing.", + }, + }, + }, +}; + +// Interactive states +export const InteractiveStates = { + render: () => ( +
+
+ + + +
+
+ ), + parameters: { + docs: { + description: { + story: "Interactive button states for visual regression testing.", + }, + }, + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + + await step("Test hover state", async () => { + const hoverButton = canvas.getByRole("button", { name: "Hover Me" }); + await userEvent.hover(hoverButton); + await new Promise((resolve) => setTimeout(resolve, 100)); + }); + + await step("Test focus state", async () => { + const focusButton = canvas.getByRole("button", { name: "Focus Me" }); + focusButton.focus(); + await new Promise((resolve) => setTimeout(resolve, 100)); + }); + + await step("Test click state", async () => { + const clickButton = canvas.getByRole("button", { name: "Click Me" }); + await userEvent.click(clickButton); + await new Promise((resolve) => setTimeout(resolve, 100)); + }); + }, +}; + +// Edge cases +export const EdgeCases = { + render: () => ( +
+
+ + +
+
+ + + + +
+
+ ), + parameters: { + docs: { + description: { + story: "Edge cases for button visual regression testing.", + }, + }, + }, +}; diff --git a/stories/Footer.responsive.stories.js b/stories/Footer.responsive.stories.js new file mode 100644 index 0000000..3f8d936 --- /dev/null +++ b/stories/Footer.responsive.stories.js @@ -0,0 +1,335 @@ +import Footer from "../app/components/Footer.js"; +import { within, userEvent } from "@storybook/test"; + +export default { + title: "Components/Footer/Responsive", + component: Footer, + parameters: { + // Chromatic configuration for responsive testing + chromatic: { + viewports: [320, 360, 480, 640, 768, 1024, 1280, 1440, 1920], + // Capture screenshots at each breakpoint + delay: 200, // Increased delay to ensure layout is stable + // Capture both light and dark themes if available + modes: { + light: {}, + dark: { + // This will be used if dark mode is implemented + colorScheme: "dark", + }, + }, + }, + // Storybook viewport configuration + viewport: { + viewports: { + xs: { + name: "Extra Small (xs)", + styles: { + width: "360px", + height: "700px", + }, + }, + sm: { + name: "Small (sm)", + styles: { + width: "640px", + height: "700px", + }, + }, + md: { + name: "Medium (md)", + styles: { + width: "768px", + height: "700px", + }, + }, + lg: { + name: "Large (lg)", + styles: { + width: "1024px", + height: "700px", + }, + }, + xl: { + name: "Extra Large (xl)", + styles: { + width: "1280px", + height: "700px", + }, + }, + xxl: { + name: "2XL (xxl)", + styles: { + width: "1440px", + height: "700px", + }, + }, + full: { + name: "Full HD (full)", + styles: { + width: "1920px", + height: "700px", + }, + }, + }, + }, + }, +}; + +// Default story - will be captured at all viewports by Chromatic +export const Default = { + parameters: { + docs: { + description: { + story: + "Footer component at different breakpoints. Chromatic will capture screenshots at 320px, 360px, 480px, 640px, 768px, 1024px, 1280px, 1440px, and 1920px viewport widths to test responsive behavior.", + }, + }, + }, +}; + +// Story for each breakpoint to make testing easier +export const ExtraSmall = { + parameters: { + viewport: { + defaultViewport: "xs", + }, + docs: { + description: { + story: + "Footer at extra small breakpoint (360px). Tests mobile layout and stacking behavior.", + }, + }, + }, +}; + +export const Small = { + parameters: { + viewport: { + defaultViewport: "sm", + }, + docs: { + description: { + story: + "Footer at small breakpoint (640px). Tests tablet layout and responsive behavior.", + }, + }, + }, +}; + +export const Medium = { + parameters: { + viewport: { + defaultViewport: "md", + }, + docs: { + description: { + story: + "Footer at medium breakpoint (768px). Tests small desktop layout.", + }, + }, + }, +}; + +export const Large = { + parameters: { + viewport: { + defaultViewport: "lg", + }, + docs: { + description: { + story: "Footer at large breakpoint (1024px). Tests desktop layout.", + }, + }, + }, +}; + +export const ExtraLarge = { + parameters: { + viewport: { + defaultViewport: "xl", + }, + docs: { + description: { + story: + "Footer at extra large breakpoint (1280px). Tests large desktop layout.", + }, + }, + }, +}; + +export const TwoXL = { + parameters: { + viewport: { + defaultViewport: "xxl", + }, + docs: { + description: { + story: + "Footer at 2XL breakpoint (1440px). Tests very large desktop layout.", + }, + }, + }, +}; + +export const FullHD = { + parameters: { + viewport: { + defaultViewport: "full", + }, + docs: { + description: { + story: + "Footer at Full HD breakpoint (1920px). Tests maximum desktop layout.", + }, + }, + }, +}; + +// Interactive story for testing user interactions +export const Interactive = { + parameters: { + docs: { + description: { + story: + "Interactive footer for testing user interactions. Check the Actions panel to see triggered events.", + }, + }, + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + + await step("Click footer links", async () => { + const useCasesLink = canvas.getByRole("link", { name: /use cases/i }); + await userEvent.click(useCasesLink); + + const learnLink = canvas.getByRole("link", { name: /learn/i }); + await userEvent.click(learnLink); + + const aboutLink = canvas.getByRole("link", { name: /about/i }); + await userEvent.click(aboutLink); + + const privacyLink = canvas.getByRole("link", { name: /privacy policy/i }); + await userEvent.click(privacyLink); + + const termsLink = canvas.getByRole("link", { name: /terms of service/i }); + await userEvent.click(termsLink); + }); + + await step("Click social media links", async () => { + const blueskyLink = canvas.getByRole("link", { + name: /follow us on bluesky/i, + }); + await userEvent.click(blueskyLink); + + const gitlabLink = canvas.getByRole("link", { + name: /follow us on gitlab/i, + }); + await userEvent.click(gitlabLink); + }); + }, +}; + +// Story for testing hover states +export const HoverStates = { + parameters: { + docs: { + description: { + story: + "Footer with hover states visible. This story captures the visual appearance when elements are hovered.", + }, + }, + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + + await step("Hover over footer links", async () => { + const useCasesLink = canvas.getByRole("link", { name: /use cases/i }); + await userEvent.hover(useCasesLink); + await new Promise((resolve) => setTimeout(resolve, 100)); + + const learnLink = canvas.getByRole("link", { name: /learn/i }); + await userEvent.hover(learnLink); + await new Promise((resolve) => setTimeout(resolve, 100)); + + const aboutLink = canvas.getByRole("link", { name: /about/i }); + await userEvent.hover(aboutLink); + await new Promise((resolve) => setTimeout(resolve, 100)); + }); + + await step("Hover over social media links", async () => { + const blueskyLink = canvas.getByRole("link", { + name: /follow us on bluesky/i, + }); + await userEvent.hover(blueskyLink); + await new Promise((resolve) => setTimeout(resolve, 100)); + + const gitlabLink = canvas.getByRole("link", { + name: /follow us on gitlab/i, + }); + await userEvent.hover(gitlabLink); + await new Promise((resolve) => setTimeout(resolve, 100)); + }); + }, +}; + +// Story for testing with long content above +export const WithLongContent = { + render: () => ( +
+
+
+

+ Footer with Long Content Above +

+

+ This story tests how the footer looks with a lot of content above + it. This helps ensure the footer maintains its visual integrity in + real-world scenarios. +

+
+ {Array.from({ length: 20 }, (_, i) => ( +
+

+ Content Block {i + 1} +

+

+ This is example content to show how the footer integrates with + page content. This block contains enough text to test layout + behavior. +

+
+ ))} +
+
+
+
+
+ ), + parameters: { + docs: { + description: { + story: + "Footer with long content above to test visual integration and layout stability.", + }, + }, + }, +}; + +// Story for testing edge cases +export const EdgeCases = { + parameters: { + viewport: { + defaultViewport: "xs", + }, + docs: { + description: { + story: + "Footer at the smallest breakpoint to test edge case behavior and ensure no layout issues.", + }, + }, + }, +}; diff --git a/stories/Header.responsive.stories.js b/stories/Header.responsive.stories.js new file mode 100644 index 0000000..a0d99c7 --- /dev/null +++ b/stories/Header.responsive.stories.js @@ -0,0 +1,382 @@ +import Header from "../app/components/Header.js"; +import { within, userEvent } from "@storybook/test"; + +export default { + title: "Components/Header/Responsive", + component: Header, + parameters: { + // Chromatic configuration for responsive testing + chromatic: { + viewports: [320, 360, 480, 640, 768, 1024, 1280, 1440, 1920], + // Capture screenshots at each breakpoint + delay: 200, // Increased delay to ensure layout is stable + // Capture both light and dark themes if available + modes: { + light: {}, + dark: { + // This will be used if dark mode is implemented + colorScheme: "dark", + }, + }, + }, + // Storybook viewport configuration + viewport: { + viewports: { + xs: { + name: "Extra Small (xs)", + styles: { + width: "360px", + height: "700px", + }, + }, + sm: { + name: "Small (sm)", + styles: { + width: "640px", + height: "700px", + }, + }, + md: { + name: "Medium (md)", + styles: { + width: "768px", + height: "700px", + }, + }, + lg: { + name: "Large (lg)", + styles: { + width: "1024px", + height: "700px", + }, + }, + xl: { + name: "Extra Large (xl)", + styles: { + width: "1280px", + height: "700px", + }, + }, + xxl: { + name: "2XL (xxl)", + styles: { + width: "1440px", + height: "700px", + }, + }, + full: { + name: "Full HD (full)", + styles: { + width: "1920px", + height: "700px", + }, + }, + }, + }, + }, + argTypes: { + onToggle: { action: "toggled" }, + }, +}; + +// Default story - will be captured at all viewports by Chromatic +export const Default = { + args: { + onToggle: () => console.log("Navigation toggled"), + }, + parameters: { + docs: { + description: { + story: + "Header component at different breakpoints. Chromatic will capture screenshots at 360px, 640px, 768px, 1024px, and 1280px viewport widths to test responsive behavior.", + }, + }, + }, +}; + +// Story for each breakpoint to make testing easier +export const ExtraSmall = { + args: { + onToggle: () => console.log("Navigation toggled"), + }, + parameters: { + viewport: { + defaultViewport: "xs", + }, + docs: { + description: { + story: + "Header at extra small breakpoint (360px). Navigation items are moved to the right section.", + }, + }, + }, +}; + +export const Small = { + args: { + onToggle: () => console.log("Navigation toggled"), + }, + parameters: { + viewport: { + defaultViewport: "sm", + }, + docs: { + description: { + story: + "Header at small breakpoint (640px). All navigation items are grouped together in the center.", + }, + }, + }, +}; + +export const Medium = { + args: { + onToggle: () => console.log("Navigation toggled"), + }, + parameters: { + viewport: { + defaultViewport: "md", + }, + docs: { + description: { + story: + "Header at medium breakpoint (768px). Navigation items are in the center, login and create rule buttons on the right.", + }, + }, + }, +}; + +export const Large = { + args: { + onToggle: () => console.log("Navigation toggled"), + }, + parameters: { + viewport: { + defaultViewport: "lg", + }, + docs: { + description: { + story: + "Header at large breakpoint (1024px). Full navigation layout with larger elements.", + }, + }, + }, +}; + +export const ExtraLarge = { + args: { + onToggle: () => console.log("Navigation toggled"), + }, + parameters: { + viewport: { + defaultViewport: "xl", + }, + docs: { + description: { + story: + "Header at extra large breakpoint (1280px). Maximum size layout with largest elements.", + }, + }, + }, +}; + +// Interactive story for testing user interactions +export const Interactive = { + args: { + onToggle: () => console.log("Navigation toggled"), + }, + parameters: { + docs: { + description: { + story: + "Interactive header for testing user interactions. Check the Actions panel to see triggered events.", + }, + }, + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + + await step("Click navigation items", async () => { + const useCasesLink = canvas.getByRole("link", { name: /use cases/i }); + await userEvent.click(useCasesLink); + + const learnLink = canvas.getByRole("link", { name: /learn/i }); + await userEvent.click(learnLink); + + const aboutLink = canvas.getByRole("link", { name: /about/i }); + await userEvent.click(aboutLink); + }); + + await step("Click authentication elements", async () => { + const loginLink = canvas.getByRole("link", { + name: /log in to your account/i, + }); + await userEvent.click(loginLink); + + const createRuleButton = canvas.getByRole("button", { + name: /create a new rule with avatar decoration/i, + }); + await userEvent.click(createRuleButton); + }); + }, +}; + +// Story for testing hover states +export const HoverStates = { + args: { + onToggle: () => console.log("Navigation toggled"), + }, + parameters: { + docs: { + description: { + story: + "Header with hover states visible. This story captures the visual appearance when elements are hovered.", + }, + }, + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + + await step("Hover over navigation items", async () => { + const useCasesLink = canvas.getByRole("link", { name: /use cases/i }); + await userEvent.hover(useCasesLink); + // Wait for hover state to be visible + await new Promise((resolve) => setTimeout(resolve, 100)); + + const learnLink = canvas.getByRole("link", { name: /learn/i }); + await userEvent.hover(learnLink); + await new Promise((resolve) => setTimeout(resolve, 100)); + + const aboutLink = canvas.getByRole("link", { name: /about/i }); + await userEvent.hover(aboutLink); + await new Promise((resolve) => setTimeout(resolve, 100)); + }); + + await step("Hover over authentication elements", async () => { + const loginLink = canvas.getByRole("link", { + name: /log in to your account/i, + }); + await userEvent.hover(loginLink); + await new Promise((resolve) => setTimeout(resolve, 100)); + + const createRuleButton = canvas.getByRole("button", { + name: /create a new rule with avatar decoration/i, + }); + await userEvent.hover(createRuleButton); + await new Promise((resolve) => setTimeout(resolve, 100)); + }); + }, +}; + +// Story for testing focus states +export const FocusStates = { + args: { + onToggle: () => console.log("Navigation toggled"), + }, + parameters: { + docs: { + description: { + story: + "Header with focus states visible. This story captures the visual appearance when elements are focused.", + }, + }, + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + + await step("Focus on navigation items", async () => { + const useCasesLink = canvas.getByRole("link", { name: /use cases/i }); + useCasesLink.focus(); + await new Promise((resolve) => setTimeout(resolve, 100)); + + const learnLink = canvas.getByRole("link", { name: /learn/i }); + learnLink.focus(); + await new Promise((resolve) => setTimeout(resolve, 100)); + + const aboutLink = canvas.getByRole("link", { name: /about/i }); + aboutLink.focus(); + await new Promise((resolve) => setTimeout(resolve, 100)); + }); + + await step("Focus on authentication elements", async () => { + const loginLink = canvas.getByRole("link", { + name: /log in to your account/i, + }); + loginLink.focus(); + await new Promise((resolve) => setTimeout(resolve, 100)); + + const createRuleButton = canvas.getByRole("button", { + name: /create a new rule with avatar decoration/i, + }); + createRuleButton.focus(); + await new Promise((resolve) => setTimeout(resolve, 100)); + }); + }, +}; + +// Story for testing with long content +export const WithLongContent = { + args: { + onToggle: () => console.log("Navigation toggled"), + }, + render: () => ( +
+
console.log("Navigation toggled")} /> +
+
+

+ Header with Long Content +

+

+ This story tests how the header looks with a lot of content below + it. This helps ensure the header maintains its visual integrity in + real-world scenarios. +

+
+ {Array.from({ length: 12 }, (_, i) => ( +
+

+ Content Block {i + 1} +

+

+ This is example content to show how the header integrates with + page content. This block contains enough text to test layout + behavior. +

+
+ ))} +
+
+
+
+ ), + parameters: { + docs: { + description: { + story: + "Header with long content below to test visual integration and layout stability.", + }, + }, + }, +}; + +// Story for testing edge cases +export const EdgeCases = { + args: { + onToggle: () => console.log("Navigation toggled"), + }, + parameters: { + viewport: { + defaultViewport: "xs", + }, + docs: { + description: { + story: + "Header at the smallest breakpoint to test edge case behavior and ensure no layout issues.", + }, + }, + }, +}; diff --git a/tests/e2e/accessibility.spec.ts b/tests/e2e/accessibility.spec.ts new file mode 100644 index 0000000..4995bae --- /dev/null +++ b/tests/e2e/accessibility.spec.ts @@ -0,0 +1,315 @@ +import { test, expect } from "@playwright/test"; +import { injectAxe, checkA11y } from "@axe-core/playwright"; + +test.describe("Accessibility Testing", () => { + test.beforeEach(async ({ page }) => { + await page.goto("/"); + }); + + test("WCAG 2.1 AA compliance - homepage", async ({ page }) => { + // Basic accessibility checks without axe-core for now + // Check for proper HTML structure + const html = page.locator("html"); + const lang = await html.getAttribute("lang"); + expect(lang).toBeTruthy(); + + // Check for main heading + const h1 = page.locator("h1").first(); + await expect(h1).toBeVisible(); + + // Check for main landmark + const main = page.locator("main, [role='main']"); + await expect(main).toBeVisible(); + + // Check for navigation + const nav = page.locator("nav, [role='navigation']").first(); + await expect(nav).toBeVisible(); + + // Check for banner + const banner = page.locator("header, [role='banner']").first(); + await expect(banner).toBeVisible(); + }); + + test("keyboard navigation - tab order", async ({ page }) => { + // Test tab navigation through all interactive elements + await page.keyboard.press("Tab"); + await expect(page.locator(":focus").first()).toBeVisible(); + + // Navigate through all focusable elements + let tabCount = 0; + const maxTabs = 50; // Prevent infinite loop + const focusedElements: string[] = []; + + while (tabCount < maxTabs) { + const focusedElement = page.locator(":focus").first(); + if ((await focusedElement.count()) === 0) { + break; + } + + // Get the tag name and accessible name of focused element + const elementInfo = await focusedElement.evaluate((el) => ({ + tagName: el.tagName.toLowerCase(), + accessibleName: + el.getAttribute("aria-label") || + el.getAttribute("alt") || + el.textContent?.trim() || + "", + role: el.getAttribute("role") || "", + })); + + focusedElements.push( + `${elementInfo.tagName}${ + elementInfo.role ? `[role="${elementInfo.role}"]` : "" + }: ${elementInfo.accessibleName}` + ); + + await page.keyboard.press("Tab"); + tabCount++; + } + + // Verify we have a reasonable number of focusable elements + expect(focusedElements.length).toBeGreaterThan(5); + console.log("Tab order:", focusedElements); + }); + + test("keyboard navigation - enter key activation", async ({ page }) => { + // Test that buttons and links can be activated with Enter key + const buttons = page.locator("button, [role='button']"); + const buttonCount = await buttons.count(); + + for (let i = 0; i < Math.min(buttonCount, 3); i++) { + const button = buttons.nth(i); + + // Try to focus the button + try { + await button.focus(); + await expect(button).toBeFocused(); + + // Test Enter key activation + await page.keyboard.press("Enter"); + await page.waitForTimeout(100); // Brief pause to see if action occurs + } catch (error) { + // If focus fails, skip this button + console.log(`Could not focus button ${i}: ${error.message}`); + continue; + } + } + }); + + test("keyboard navigation - escape key", async ({ page }) => { + // Test Escape key functionality + await page.keyboard.press("Escape"); + // Should handle escape gracefully without errors + }); + + test("screen reader compatibility - semantic structure", async ({ page }) => { + // Check for proper heading structure + const headings = page.locator("h1, h2, h3, h4, h5, h6"); + const headingCount = await headings.count(); + expect(headingCount).toBeGreaterThan(0); + + // Check for main landmark + const main = page.locator("main, [role='main']"); + await expect(main).toBeVisible(); + + // Check for navigation landmark + const nav = page.locator("nav, [role='navigation']").first(); + await expect(nav).toBeVisible(); + + // Check for banner landmark + const banner = page.locator("header, [role='banner']").first(); + await expect(banner).toBeVisible(); + + // Check for contentinfo landmark + const contentinfo = page.locator("footer, [role='contentinfo']").first(); + await expect(contentinfo).toBeVisible(); + }); + + test("screen reader compatibility - ARIA labels", async ({ page }) => { + // Check that interactive elements have proper labels + const buttons = page.locator("button"); + const buttonCount = await buttons.count(); + + for (let i = 0; i < Math.min(buttonCount, 5); i++) { + const button = buttons.nth(i); + const hasLabel = await button.evaluate((el) => { + return ( + el.getAttribute("aria-label") || + el.getAttribute("aria-labelledby") || + el.textContent?.trim() || + el.getAttribute("title") + ); + }); + expect(hasLabel).toBeTruthy(); + } + + // Check that images have alt text + const images = page.locator("img"); + const imageCount = await images.count(); + + for (let i = 0; i < Math.min(imageCount, 5); i++) { + const image = images.nth(i); + const altText = await image.getAttribute("alt"); + // Decorative images can have empty alt, but should have alt attribute + expect(altText).not.toBeNull(); + } + }); + + test("color contrast - text elements", async ({ page }) => { + // Basic color contrast check - verify text is readable + const textElements = page.locator("p, h1, h2, h3, h4, h5, h6, span, div"); + const textCount = await textElements.count(); + expect(textCount).toBeGreaterThan(0); + + // Check that text elements have sufficient contrast by verifying they're visible + for (let i = 0; i < Math.min(textCount, 5); i++) { + const element = textElements.nth(i); + const isVisible = await element.isVisible(); + if (isVisible) { + const text = await element.textContent(); + expect(text?.trim()).toBeTruthy(); + } + } + }); + + test("focus indicators - visible focus", async ({ page }) => { + // Test that focus indicators are visible + const focusableElements = page.locator( + "button, a, input, textarea, select, [tabindex]" + ); + const elementCount = await focusableElements.count(); + + for (let i = 0; i < Math.min(elementCount, 3); i++) { + const element = focusableElements.nth(i); + await element.focus(); + + // Check if element has visible focus indicator + const hasFocusIndicator = await element.evaluate((el) => { + const style = window.getComputedStyle(el); + return ( + style.outline !== "none" || + style.boxShadow !== "none" || + style.borderColor !== "transparent" || + el.classList.contains("focus-visible") || + el.getAttribute("data-focus-visible") + ); + }); + + expect(hasFocusIndicator).toBeTruthy(); + } + }); + + test("skip links - if present", async ({ page }) => { + // Check for skip links (common accessibility feature) + const skipLinks = page.locator("a[href^='#'], a[href*='skip']"); + const skipLinkCount = await skipLinks.count(); + + if (skipLinkCount > 0) { + // Test skip link functionality + const firstSkipLink = skipLinks.first(); + if (await firstSkipLink.isVisible()) { + await firstSkipLink.click(); + // Should navigate to target without errors + } + } + }); + + test("form accessibility - if forms present", async ({ page }) => { + // Check form accessibility + const forms = page.locator("form"); + const formCount = await forms.count(); + + if (formCount > 0) { + const form = forms.first(); + + // Check for form labels + const inputs = form.locator("input, textarea, select"); + const inputCount = await inputs.count(); + + for (let i = 0; i < Math.min(inputCount, 3); i++) { + const input = inputs.nth(i); + const hasLabel = await input.evaluate((el) => { + const id = el.getAttribute("id"); + if (id) { + const label = document.querySelector(`label[for="${id}"]`); + if (label) return true; + } + return ( + el.getAttribute("aria-label") || + el.getAttribute("aria-labelledby") || + el.getAttribute("placeholder") + ); + }); + expect(hasLabel).toBeTruthy(); + } + } + }); + + test("responsive accessibility - mobile viewport", async ({ page }) => { + // Test accessibility on mobile viewport + await page.setViewportSize({ width: 375, height: 667 }); + + // Basic accessibility checks for mobile + const html = page.locator("html"); + const lang = await html.getAttribute("lang"); + expect(lang).toBeTruthy(); + + // Check that main content is still accessible + const main = page.locator("main, [role='main']"); + await expect(main).toBeVisible(); + + // Check that navigation is still accessible + const nav = page.locator("nav, [role='navigation']").first(); + await expect(nav).toBeVisible(); + }); + + test("responsive accessibility - tablet viewport", async ({ page }) => { + // Test accessibility on tablet viewport + await page.setViewportSize({ width: 768, height: 1024 }); + + // Basic accessibility checks for tablet + const html = page.locator("html"); + const lang = await html.getAttribute("lang"); + expect(lang).toBeTruthy(); + + // Check that main content is still accessible + const main = page.locator("main, [role='main']"); + await expect(main).toBeVisible(); + + // Check that navigation is still accessible + const nav = page.locator("nav, [role='navigation']").first(); + await expect(nav).toBeVisible(); + }); + + test("language and internationalization", async ({ page }) => { + // Check for proper language declaration + const html = page.locator("html"); + const lang = await html.getAttribute("lang"); + expect(lang).toBeTruthy(); + expect(lang).toMatch(/^[a-z]{2}(-[A-Z]{2})?$/); // Valid language code format + + // Check for proper direction if RTL language + if (lang?.includes("ar") || lang?.includes("he") || lang?.includes("fa")) { + const dir = await html.getAttribute("dir"); + expect(dir).toBe("rtl"); + } + }); + + test("error handling accessibility", async ({ page }) => { + // Test that error messages are accessible + // This would typically involve triggering errors and checking ARIA attributes + // For now, we'll check that the page handles errors gracefully + + // Simulate a network error + await page.route("**/*", (route) => { + route.abort(); + }); + + try { + await page.reload(); + } catch (error) { + // Page should handle errors gracefully + await expect(page.locator("body")).toBeVisible(); + } + }); +}); diff --git a/tests/e2e/axe.ts b/tests/e2e/axe.ts new file mode 100644 index 0000000..19147d4 --- /dev/null +++ b/tests/e2e/axe.ts @@ -0,0 +1,10 @@ +import { injectAxe, checkA11y } from "@axe-core/playwright"; + +export async function runA11y(page, options = {}) { + await injectAxe(page); + await checkA11y(page, undefined, { + detailedReport: true, + detailedReportOptions: { html: true }, + ...options, + }); +} diff --git a/tests/e2e/edge-cases.spec.ts b/tests/e2e/edge-cases.spec.ts new file mode 100644 index 0000000..ce302ef --- /dev/null +++ b/tests/e2e/edge-cases.spec.ts @@ -0,0 +1,409 @@ +import { test, expect } from "@playwright/test"; + +test.describe("Edge Cases and Error Scenarios", () => { + test.beforeEach(async ({ page }) => { + await page.goto("/"); + }); + + test("handles slow network conditions", async ({ page }) => { + // Simulate slow network + await page.route("**/*", (route) => { + // Add 2 second delay to all requests + setTimeout(() => route.continue(), 2000); + }); + + // Reload page with slow network + await page.reload(); + + // Page should still load eventually + await expect(page.locator("text=Collaborate")).toBeVisible({ + timeout: 10000, + }); + }); + + test("handles offline mode gracefully", async ({ page }) => { + // Set offline mode + await page.setOffline(true); + + // Reload page + await page.reload(); + + // Should show some content even offline + await expect(page.locator("body")).toBeVisible(); + + // Restore online mode + await page.setOffline(false); + }); + + test("handles rapid user interactions", async ({ page }) => { + // Rapidly click buttons + const buttons = page.locator("button"); + const buttonCount = await buttons.count(); + + for (let i = 0; i < Math.min(buttonCount, 5); i++) { + await buttons.nth(i).click(); + await page.waitForTimeout(100); // Very short delay + } + + // Page should remain stable + await expect(page.locator("text=Collaborate")).toBeVisible(); + }); + + test("handles rapid scrolling", async ({ page }) => { + // Rapid scroll to bottom + await page.evaluate(() => { + for (let i = 0; i < 10; i++) { + window.scrollTo(0, document.body.scrollHeight * (i / 10)); + } + }); + + // Should end up at bottom + await expect(page.locator("footer")).toBeVisible(); + }); + + test("handles viewport size changes", async ({ page }) => { + // Rapidly change viewport sizes + const viewports = [ + { width: 375, height: 667 }, + { width: 768, height: 1024 }, + { width: 1440, height: 900 }, + { width: 1920, height: 1080 }, + ]; + + for (const viewport of viewports) { + await page.setViewportSize(viewport); + await page.waitForTimeout(500); + + // Content should remain visible + await expect(page.locator("text=Collaborate")).toBeVisible(); + } + }); + + test("handles browser back/forward navigation", async ({ page }) => { + // Navigate to a section + await page + .locator('button:has-text("Learn how CommunityRule works")') + .first() + .click(); + + // Go back + await page.goBack(); + + // Should be back at homepage + await expect(page).toHaveURL("/"); + await expect(page.locator("text=Collaborate")).toBeVisible(); + + // Go forward + await page.goForward(); + + // Should be back to the section + await expect( + page.locator('h2:has-text("How CommunityRule works")') + ).toBeVisible(); + }); + + test("handles page refresh during interactions", async ({ page }) => { + // Start an interaction + await page + .locator('button:has-text("Learn how CommunityRule works")') + .first() + .click(); + + // Refresh page during interaction + await page.reload(); + + // Should reload successfully + await expect(page.locator("text=Collaborate")).toBeVisible(); + }); + + test("handles multiple browser tabs", async ({ page, context }) => { + // Open multiple tabs + const page1 = await context.newPage(); + const page2 = await context.newPage(); + + // Navigate all tabs to homepage + await page1.goto("/"); + await page2.goto("/"); + + // Interact with each tab + await page + .locator('button:has-text("Learn how CommunityRule works")') + .first() + .click(); + await page1.locator("text=Consensus clusters").click(); + await page2.locator('button:has-text("Ask an organizer")').first().click(); + + // All tabs should work independently + await expect( + page.locator('h2:has-text("How CommunityRule works")') + ).toBeVisible(); + await expect(page1.locator("text=Consensus clusters")).toBeVisible(); + await expect(page2.locator("text=Still have questions?")).toBeVisible(); + + // Close extra tabs + await page1.close(); + await page2.close(); + }); + + test("handles JavaScript errors gracefully", async ({ page }) => { + // Inject a JavaScript error + await page.evaluate(() => { + // Create a temporary error handler + const originalError = console.error; + console.error = () => {}; // Suppress error logging + + // Trigger a harmless error + try { + throw new Error("Test error"); + } catch (e) { + // Error handled + } + + console.error = originalError; + }); + + // Page should continue to function + await expect(page.locator("text=Collaborate")).toBeVisible(); + await page + .locator('button:has-text("Learn how CommunityRule works")') + .first() + .click(); + }); + + test("handles missing images gracefully", async ({ page }) => { + // Block image requests + await page.route("**/*.{png,jpg,jpeg,svg,webp}", (route) => { + route.abort(); + }); + + // Reload page + await page.reload(); + + // Page should still function without images + await expect(page.locator("text=Collaborate")).toBeVisible(); + await page + .locator('button:has-text("Learn how CommunityRule works")') + .first() + .click(); + }); + + test("handles CSS loading failures", async ({ page }) => { + // Block CSS requests + await page.route("**/*.css", (route) => { + route.abort(); + }); + + // Reload page + await page.reload(); + + // Page should still function without styles + await expect(page.locator("text=Collaborate")).toBeVisible(); + await page + .locator('button:has-text("Learn how CommunityRule works")') + .first() + .click(); + }); + + test("handles font loading failures", async ({ page }) => { + // Block font requests + await page.route("**/*.{woff,woff2,ttf,otf}", (route) => { + route.abort(); + }); + + // Reload page + await page.reload(); + + // Page should still function with fallback fonts + await expect(page.locator("text=Collaborate")).toBeVisible(); + await page + .locator('button:has-text("Learn how CommunityRule works")') + .first() + .click(); + }); + + test("handles memory pressure", async ({ page }) => { + // Simulate memory pressure by creating many elements + await page.evaluate(() => { + // Create temporary elements to simulate memory usage + for (let i = 0; i < 1000; i++) { + const div = document.createElement("div"); + div.textContent = `Test element ${i}`; + document.body.appendChild(div); + } + + // Clean up + setTimeout(() => { + const testElements = document.querySelectorAll( + 'div[textContent*="Test element"]' + ); + testElements.forEach((el) => el.remove()); + }, 100); + }); + + // Page should remain functional + await expect(page.locator("text=Collaborate")).toBeVisible(); + await page + .locator('button:has-text("Learn how CommunityRule works")') + .first() + .click(); + }); + + test("handles long content gracefully", async ({ page }) => { + // Add a lot of content to test scrolling performance + await page.evaluate(() => { + const container = document.createElement("div"); + container.style.height = "10000px"; + container.style.background = "linear-gradient(red, blue)"; + document.body.appendChild(container); + }); + + // Scroll through the content + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + + // Should handle long content without issues + await expect(page.locator("text=Collaborate")).toBeVisible(); + }); + + test("handles focus management", async ({ page }) => { + // Test focus trapping and management + await page.keyboard.press("Tab"); + await expect(page.locator(":focus")).toBeVisible(); + + // Navigate through focusable elements + for (let i = 0; i < 10; i++) { + await page.keyboard.press("Tab"); + await expect(page.locator(":focus")).toBeVisible(); + } + + // Test Shift+Tab for reverse navigation + for (let i = 0; i < 5; i++) { + await page.keyboard.press("Shift+Tab"); + await expect(page.locator(":focus")).toBeVisible(); + } + }); + + test("handles keyboard shortcuts", async ({ page }) => { + // Test common keyboard shortcuts + await page.keyboard.press("Home"); + await page.keyboard.press("End"); + await page.keyboard.press("PageUp"); + await page.keyboard.press("PageDown"); + + // Page should handle shortcuts gracefully + await expect(page.locator("text=Collaborate")).toBeVisible(); + }); + + test("handles copy/paste operations", async ({ page }) => { + // Test text selection and copy + await page.locator("text=Collaborate").selectText(); + await page.keyboard.press("Control+c"); + + // Test paste (should work in input fields if any) + const inputs = page.locator("input, textarea"); + if ((await inputs.count()) > 0) { + await inputs.first().click(); + await page.keyboard.press("Control+v"); + } + }); + + test("handles right-click context menu", async ({ page }) => { + // Test right-click on various elements + await page.locator("text=Collaborate").click({ button: "right" }); + await page + .locator('button:has-text("Learn how CommunityRule works")') + .first() + .click({ button: "right" }); + await page + .locator('img[alt="Hero illustration"]') + .click({ button: "right" }); + + // Should handle right-clicks gracefully + await expect(page.locator("text=Collaborate")).toBeVisible(); + }); + + test("handles drag and drop operations", async ({ page }) => { + // Test drag and drop (if applicable) + const draggableElements = page.locator('[draggable="true"]'); + const dropZones = page.locator('[data-testid*="drop"], [class*="drop"]'); + + if ( + (await draggableElements.count()) > 0 && + (await dropZones.count()) > 0 + ) { + await draggableElements.first().dragTo(dropZones.first()); + } + + // Page should handle drag operations gracefully + await expect(page.locator("text=Collaborate")).toBeVisible(); + }); + + test("handles print functionality", async ({ page }) => { + // Test print functionality + await page.evaluate(() => { + // Mock print function + window.print = () => {}; + }); + + // Trigger print + await page.keyboard.press("Control+p"); + + // Should handle print gracefully + await expect(page.locator("text=Collaborate")).toBeVisible(); + }); + + test("handles browser zoom", async ({ page }) => { + // Test different zoom levels + await page.evaluate(() => { + document.body.style.zoom = "0.5"; + }); + + await expect(page.locator("text=Collaborate")).toBeVisible(); + + await page.evaluate(() => { + document.body.style.zoom = "2.0"; + }); + + await expect(page.locator("text=Collaborate")).toBeVisible(); + + // Reset zoom + await page.evaluate(() => { + document.body.style.zoom = "1.0"; + }); + }); + + test("handles high contrast mode", async ({ page }) => { + // Simulate high contrast mode + await page.evaluate(() => { + document.body.style.filter = "contrast(200%)"; + }); + + // Content should remain readable + await expect(page.locator("text=Collaborate")).toBeVisible(); + await page + .locator('button:has-text("Learn how CommunityRule works")') + .first() + .click(); + + // Reset contrast + await page.evaluate(() => { + document.body.style.filter = "none"; + }); + }); + + test("handles reduced motion preferences", async ({ page }) => { + // Simulate reduced motion preference + await page.evaluate(() => { + document.documentElement.style.setProperty( + "--prefers-reduced-motion", + "reduce" + ); + }); + + // Page should respect reduced motion + await expect(page.locator("text=Collaborate")).toBeVisible(); + await page + .locator('button:has-text("Learn how CommunityRule works")') + .first() + .click(); + }); +}); diff --git a/tests/e2e/footer.responsive.spec.js b/tests/e2e/footer.responsive.spec.js new file mode 100644 index 0000000..c19d98b --- /dev/null +++ b/tests/e2e/footer.responsive.spec.js @@ -0,0 +1,242 @@ +import { test, expect } from "@playwright/test"; + +const breakpoints = [ + { name: "xs", width: 320, height: 700 }, + { name: "sm", width: 360, height: 700 }, + { name: "md", width: 480, height: 700 }, + { name: "lg", width: 640, height: 700 }, + { name: "xl", width: 768, height: 700 }, + { name: "2xl", width: 1024, height: 700 }, + { name: "3xl", width: 1280, height: 700 }, + { name: "4xl", width: 1440, height: 700 }, + { name: "full", width: 1920, height: 700 }, +]; + +for (const bp of breakpoints) { + test.describe(`Footer responsive behavior at ${bp.name} breakpoint`, () => { + test.beforeEach(async ({ page }) => { + await page.setViewportSize({ width: bp.width, height: bp.height }); + await page.goto("/"); + }); + + test(`footer layout at ${bp.name}`, async ({ page }) => { + const footer = page.getByRole("contentinfo"); + await expect(footer).toBeVisible(); + + // Check that footer content is visible + const footerContent = page.locator("footer"); + await expect(footerContent).toBeVisible(); + }); + + test(`footer navigation items visibility at ${bp.name}`, async ({ + page, + }) => { + // All breakpoints should have navigation items + await expect( + page.getByRole("link", { name: /use cases/i }) + ).toBeVisible(); + await expect(page.getByRole("link", { name: /learn/i })).toBeVisible(); + await expect(page.getByRole("link", { name: /about/i })).toBeVisible(); + }); + + test(`footer legal links visibility at ${bp.name}`, async ({ page }) => { + // All breakpoints should have legal links + await expect( + page.getByRole("link", { name: /privacy policy/i }) + ).toBeVisible(); + await expect( + page.getByRole("link", { name: /terms of service/i }) + ).toBeVisible(); + }); + + test(`footer social links visibility at ${bp.name}`, async ({ page }) => { + // All breakpoints should have social links + await expect( + page.getByRole("link", { name: /follow us on bluesky/i }) + ).toBeVisible(); + await expect( + page.getByRole("link", { name: /follow us on gitlab/i }) + ).toBeVisible(); + }); + + test(`footer logo visibility at ${bp.name}`, async ({ page }) => { + // Logo should be visible at all breakpoints + const logo = page.locator('[data-testid="logo-wrapper"]').first(); + await expect(logo).toBeVisible(); + }); + + // Breakpoint-specific tests + if (bp.name === "xs") { + test("xs breakpoint specific behavior", async ({ page }) => { + // At xs, footer should stack vertically + const footer = page.locator("footer"); + await expect(footer).toBeVisible(); + + // Check that content is properly stacked + const footerContent = page.locator("footer > div"); + await expect(footerContent).toBeVisible(); + }); + } + + if (bp.name === "md") { + test("md breakpoint specific behavior", async ({ page }) => { + // At md, footer should have proper spacing + const footer = page.locator("footer"); + await expect(footer).toBeVisible(); + }); + } + + if (bp.name === "xl") { + test("xl breakpoint specific behavior", async ({ page }) => { + // At xl, footer should have full layout + const footer = page.locator("footer"); + await expect(footer).toBeVisible(); + }); + } + }); +} + +// Visual regression tests +test.describe("Footer visual regression", () => { + test("footer visual consistency across breakpoints", async ({ page }) => { + // Test visual consistency at all breakpoints + for (const bp of breakpoints) { + await page.setViewportSize({ width: bp.width, height: bp.height }); + await page.goto("/"); + + // Scroll to footer + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + await page.waitForTimeout(500); + + // Take a screenshot for visual regression testing + await expect(page.locator("footer").first()).toHaveScreenshot( + `footer-${bp.name}.png` + ); + } + }); + + test("footer hover states visual consistency", async ({ page }) => { + // Test hover states at key breakpoints + const keyBreakpoints = [ + { name: "xs", width: 320, height: 700 }, + { name: "md", width: 768, height: 700 }, + { name: "xl", width: 1280, height: 700 }, + ]; + + for (const bp of keyBreakpoints) { + await page.setViewportSize({ width: bp.width, height: bp.height }); + await page.goto("/"); + + // Scroll to footer + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + await page.waitForTimeout(500); + + // Test hover on navigation items + const useCasesLink = page.getByRole("link", { name: /use cases/i }); + await useCasesLink.hover(); + await page.waitForTimeout(200); + await expect(page.locator("footer").first()).toHaveScreenshot( + `footer-${bp.name}-hover-nav.png` + ); + + // Test hover on social links + const blueskyLink = page.getByRole("link", { + name: /follow us on bluesky/i, + }); + await blueskyLink.hover(); + await page.waitForTimeout(200); + await expect(page.locator("footer").first()).toHaveScreenshot( + `footer-${bp.name}-hover-social.png` + ); + } + }); + + test("footer focus states visual consistency", async ({ page }) => { + // Test focus states at key breakpoints + const keyBreakpoints = [ + { name: "xs", width: 320, height: 700 }, + { name: "md", width: 768, height: 700 }, + { name: "xl", width: 1280, height: 700 }, + ]; + + for (const bp of keyBreakpoints) { + await page.setViewportSize({ width: bp.width, height: bp.height }); + await page.goto("/"); + + // Scroll to footer + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + await page.waitForTimeout(500); + + // Test focus on navigation items + const useCasesLink = page.getByRole("link", { name: /use cases/i }); + await useCasesLink.focus(); + await page.waitForTimeout(200); + await expect(page.locator("footer").first()).toHaveScreenshot( + `footer-${bp.name}-focus-nav.png` + ); + + // Test focus on social links + const blueskyLink = page.getByRole("link", { + name: /follow us on bluesky/i, + }); + await blueskyLink.focus(); + await page.waitForTimeout(200); + await expect(page.locator("footer").first()).toHaveScreenshot( + `footer-${bp.name}-focus-social.png` + ); + } + }); +}); + +// Additional responsive behavior tests +test.describe("Footer responsive behavior", () => { + test("footer maintains proper layout across breakpoints", async ({ + page, + }) => { + // Test that footer doesn't break at edge cases + const edgeCases = [ + { width: 320, height: 700 }, // Very small + { width: 1920, height: 700 }, // Very large + ]; + + for (const viewport of edgeCases) { + await page.setViewportSize(viewport); + await page.goto("/"); + + // Scroll to footer + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + + const footer = page.getByRole("contentinfo"); + await expect(footer).toBeVisible(); + } + }); + + test("footer elements are properly accessible across breakpoints", async ({ + page, + }) => { + // Test accessibility at different breakpoints + for (const bp of breakpoints) { + await page.setViewportSize({ width: bp.width, height: bp.height }); + await page.goto("/"); + + // Scroll to footer + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + + // Check that all interactive elements are accessible + const interactiveElements = [ + page.getByRole("link", { name: /use cases/i }), + page.getByRole("link", { name: /learn/i }), + page.getByRole("link", { name: /about/i }), + page.getByRole("link", { name: /privacy policy/i }), + page.getByRole("link", { name: /terms of service/i }), + page.getByRole("link", { name: /follow us on bluesky/i }), + page.getByRole("link", { name: /follow us on gitlab/i }), + ]; + + for (const element of interactiveElements) { + await expect(element).toBeVisible(); + await expect(element).toBeEnabled(); + } + } + }); +}); diff --git a/tests/e2e/header.responsive.spec.js b/tests/e2e/header.responsive.spec.js new file mode 100644 index 0000000..c49ebd1 --- /dev/null +++ b/tests/e2e/header.responsive.spec.js @@ -0,0 +1,272 @@ +import { test, expect } from "@playwright/test"; + +const breakpoints = [ + { name: "xs", width: 320, height: 700 }, + { name: "sm", width: 360, height: 700 }, + { name: "md", width: 480, height: 700 }, + { name: "lg", width: 640, height: 700 }, + { name: "xl", width: 768, height: 700 }, + { name: "2xl", width: 1024, height: 700 }, + { name: "3xl", width: 1280, height: 700 }, + { name: "4xl", width: 1440, height: 700 }, + { name: "full", width: 1920, height: 700 }, +]; + +for (const bp of breakpoints) { + test.describe(`Header responsive behavior at ${bp.name} breakpoint`, () => { + test.beforeEach(async ({ page }) => { + await page.setViewportSize({ width: bp.width, height: bp.height }); + await page.goto("/"); + }); + + test(`header layout at ${bp.name}`, async ({ page }) => { + const nav = page.getByRole("navigation", { name: /main navigation/i }); + await expect(nav).toBeVisible(); + + // Check that header banner is visible + const header = page.getByRole("banner", { + name: /main navigation header/i, + }); + await expect(header).toBeVisible(); + }); + + test(`navigation items visibility at ${bp.name}`, async ({ page }) => { + // All breakpoints should have navigation items + await expect( + page.getByRole("link", { name: /use cases/i }) + ).toBeVisible(); + await expect(page.getByRole("link", { name: /learn/i })).toBeVisible(); + await expect(page.getByRole("link", { name: /about/i })).toBeVisible(); + }); + + test(`authentication elements visibility at ${bp.name}`, async ({ + page, + }) => { + // All breakpoints should have login button + await expect( + page.getByRole("link", { name: /log in to your account/i }) + ).toBeVisible(); + + // All breakpoints should have create rule button + await expect( + page.getByRole("button", { + name: /create a new rule with avatar decoration/i, + }) + ).toBeVisible(); + }); + + test(`logo visibility at ${bp.name}`, async ({ page }) => { + // Logo should be visible at all breakpoints + const logo = page.locator('[data-testid="logo-wrapper"]').first(); + await expect(logo).toBeVisible(); + }); + + // Breakpoint-specific tests + if (bp.name === "xs") { + test("xs breakpoint specific behavior", async ({ page }) => { + // At xs, navigation items should be in the right section + const authXs = page.locator('[data-testid="auth-xs"]'); + await expect(authXs).toBeVisible(); + + // Navigation items should be in the auth section at xs + const useCasesLink = page.getByRole("link", { name: /use cases/i }); + await expect(useCasesLink).toBeVisible(); + + // Login button should be in the auth section + const loginButton = page.getByRole("link", { + name: /log in to your account/i, + }); + await expect(loginButton).toBeVisible(); + + // Create rule button should be visible + const createRuleButton = page.getByRole("button", { + name: /create a new rule with avatar decoration/i, + }); + await expect(createRuleButton).toBeVisible(); + }); + } + + if (bp.name === "sm") { + test("sm breakpoint specific behavior", async ({ page }) => { + // At sm, navigation should be in the center section + const navSm = page.locator('[data-testid="nav-sm"]'); + await expect(navSm).toBeVisible(); + + // Auth section should only have create rule button + const authSm = page.locator('[data-testid="auth-sm"]'); + await expect(authSm).toBeVisible(); + }); + } + + if (bp.name === "md") { + test("md breakpoint specific behavior", async ({ page }) => { + // At md, navigation should be in the center section + const navMd = page.locator('[data-testid="nav-md"]'); + await expect(navMd).toBeVisible(); + + // Auth section should have login and create rule button + const authMd = page.locator('[data-testid="auth-md"]'); + await expect(authMd).toBeVisible(); + }); + } + + if (bp.name === "lg") { + test("lg breakpoint specific behavior", async ({ page }) => { + // At lg, navigation should be in the center section + const navLg = page.locator('[data-testid="nav-lg"]'); + await expect(navLg).toBeVisible(); + + // Auth section should have login and create rule button + const authLg = page.locator('[data-testid="auth-lg"]'); + await expect(authLg).toBeVisible(); + }); + } + + if (bp.name === "xl") { + test("xl breakpoint specific behavior", async ({ page }) => { + // At xl, navigation should be in the center section + const navXl = page.locator('[data-testid="nav-xl"]'); + await expect(navXl).toBeVisible(); + + // Auth section should have login and create rule button + const authXl = page.locator('[data-testid="auth-xl"]'); + await expect(authXl).toBeVisible(); + }); + } + }); +} + +// Visual regression tests +test.describe("Header visual regression", () => { + test("header visual consistency across breakpoints", async ({ page }) => { + // Test visual consistency at all breakpoints + for (const bp of breakpoints) { + await page.setViewportSize({ width: bp.width, height: bp.height }); + await page.goto("/"); + + // Wait for layout to stabilize + await page.waitForTimeout(500); + + // Take a screenshot for visual regression testing + await expect(page.locator("header").first()).toHaveScreenshot( + `header-${bp.name}.png` + ); + } + }); + + test("header hover states visual consistency", async ({ page }) => { + // Test hover states at key breakpoints + const keyBreakpoints = [ + { name: "xs", width: 320, height: 700 }, + { name: "md", width: 768, height: 700 }, + { name: "xl", width: 1280, height: 700 }, + ]; + + for (const bp of keyBreakpoints) { + await page.setViewportSize({ width: bp.width, height: bp.height }); + await page.goto("/"); + + // Test hover on navigation items + const useCasesLink = page.getByRole("link", { name: /use cases/i }); + await useCasesLink.hover(); + await page.waitForTimeout(200); + await expect(page.locator("header").first()).toHaveScreenshot( + `header-${bp.name}-hover-nav.png` + ); + + // Test hover on create rule button + const createRuleButton = page.getByRole("button", { + name: /create a new rule with avatar decoration/i, + }); + await createRuleButton.hover(); + await page.waitForTimeout(200); + await expect(page.locator("header").first()).toHaveScreenshot( + `header-${bp.name}-hover-button.png` + ); + } + }); + + test("header focus states visual consistency", async ({ page }) => { + // Test focus states at key breakpoints + const keyBreakpoints = [ + { name: "xs", width: 320, height: 700 }, + { name: "md", width: 768, height: 700 }, + { name: "xl", width: 1280, height: 700 }, + ]; + + for (const bp of keyBreakpoints) { + await page.setViewportSize({ width: bp.width, height: bp.height }); + await page.goto("/"); + + // Test focus on navigation items + const useCasesLink = page.getByRole("link", { name: /use cases/i }); + await useCasesLink.focus(); + await page.waitForTimeout(200); + await expect(page.locator("header").first()).toHaveScreenshot( + `header-${bp.name}-focus-nav.png` + ); + + // Test focus on create rule button + const createRuleButton = page.getByRole("button", { + name: /create a new rule with avatar decoration/i, + }); + await createRuleButton.focus(); + await page.waitForTimeout(200); + await expect(page.locator("header").first()).toHaveScreenshot( + `header-${bp.name}-focus-button.png` + ); + } + }); +}); + +// Additional responsive behavior tests +test.describe("Header responsive behavior", () => { + test("header maintains proper layout across breakpoints", async ({ + page, + }) => { + // Test that header doesn't break at edge cases + const edgeCases = [ + { width: 320, height: 700 }, // Very small + { width: 1920, height: 700 }, // Very large + ]; + + for (const viewport of edgeCases) { + await page.setViewportSize(viewport); + await page.goto("/"); + + const header = page.getByRole("banner", { + name: /main navigation header/i, + }); + await expect(header).toBeVisible(); + + const nav = page.getByRole("navigation", { name: /main navigation/i }); + await expect(nav).toBeVisible(); + } + }); + + test("header elements are properly accessible across breakpoints", async ({ + page, + }) => { + // Test accessibility at different breakpoints + for (const bp of breakpoints) { + await page.setViewportSize({ width: bp.width, height: bp.height }); + await page.goto("/"); + + // Check that all interactive elements are accessible + const interactiveElements = [ + page.getByRole("link", { name: /use cases/i }), + page.getByRole("link", { name: /learn/i }), + page.getByRole("link", { name: /about/i }), + page.getByRole("link", { name: /log in to your account/i }), + page.getByRole("button", { + name: /create a new rule with avatar decoration/i, + }), + ]; + + for (const element of interactiveElements) { + await expect(element).toBeVisible(); + await expect(element).toBeEnabled(); + } + } + }); +}); diff --git a/tests/e2e/homepage.spec.ts b/tests/e2e/homepage.spec.ts new file mode 100644 index 0000000..75475a8 --- /dev/null +++ b/tests/e2e/homepage.spec.ts @@ -0,0 +1,380 @@ +import { test, expect } from "@playwright/test"; +import { runA11y } from "./axe"; + +test.describe("Homepage", () => { + test.beforeEach(async ({ page }) => { + await page.goto("/"); + }); + + test("homepage loads successfully with all sections", async ({ page }) => { + // Check page title and meta + await expect(page).toHaveTitle(/CommunityRule/); + + // Check main sections are present + await expect( + page.locator("h1, h2").filter({ hasText: "Collaborate" }) + ).toBeVisible(); + await expect( + page.locator("h2").filter({ hasText: "How CommunityRule works" }) + ).toBeVisible(); + await expect( + page.locator("h2").filter({ hasText: "We've got your back" }) + ).toBeVisible(); + + // Check key components are rendered + await expect(page.locator('img[alt="Hero illustration"]')).toBeVisible(); + await expect( + page.locator("text=Trusted by leading cooperators") + ).toBeVisible(); + await expect(page.locator("text=Jo Freeman")).toBeVisible(); + }); + + test("hero banner section functionality", async ({ page }) => { + // Check hero content + await expect(page.locator("text=Collaborate")).toBeVisible(); + await expect(page.locator("text=with clarity")).toBeVisible(); + await expect( + page.locator("text=Help your community make important decisions") + ).toBeVisible(); + + // Check CTA button + const ctaButton = page + .locator('button:has-text("Learn how CommunityRule works")') + .first(); + await expect(ctaButton).toBeVisible(); + await expect(ctaButton).toBeEnabled(); + + // Test button interaction + await ctaButton.click(); + // Should scroll to the numbered cards section + await expect( + page.locator('h2:has-text("How CommunityRule works")') + ).toBeVisible(); + }); + + test("logo wall section displays correctly", async ({ page }) => { + // Check section label + await expect( + page.locator("text=Trusted by leading cooperators") + ).toBeVisible(); + + // Check logos are present + await expect(page.locator('img[alt="Food Not Bombs"]')).toBeVisible(); + await expect(page.locator('img[alt="Start COOP"]')).toBeVisible(); + await expect(page.locator('img[alt="Metagov"]')).toBeVisible(); + await expect(page.locator('img[alt="Open Civics"]')).toBeVisible(); + await expect(page.locator('img[alt="Mutual Aid CO"]')).toBeVisible(); + await expect(page.locator('img[alt="CU Boulder"]')).toBeVisible(); + + // Check logos have proper attributes + const logos = page.locator('img[alt*="Logo"]'); + await expect(logos).toHaveCount(6); + + // Test hover effects (visual test) + await page.locator('img[alt="Food Not Bombs"]').hover(); + // Should see hover state (opacity change) + }); + + test("numbered cards section functionality", async ({ page }) => { + // Check section header + await expect( + page.locator('h2:has-text("How CommunityRule works")') + ).toBeVisible(); + await expect( + page.locator("text=Here's a quick overview of the process") + ).toBeVisible(); + + // Check all three cards are present + await expect( + page.locator("text=Document how your community makes decisions") + ).toBeVisible(); + await expect( + page.locator("text=Build an operating manual for a successful community") + ).toBeVisible(); + await expect( + page.locator( + "text=Get a link to your manual for your group to review and evolve" + ) + ).toBeVisible(); + + // Check numbered indicators + await expect(page.locator("text=1")).toBeVisible(); + await expect(page.locator("text=2")).toBeVisible(); + await expect(page.locator("text=3")).toBeVisible(); + + // Check CTA buttons + await expect( + page.locator('button:has-text("Create CommunityRule")') + ).toBeVisible(); + await expect( + page.locator('button:has-text("See how it works")') + ).toBeVisible(); + }); + + test("rule stack section interactions", async ({ page }) => { + // Check all four rule cards are present + await expect(page.locator("text=Consensus clusters")).toBeVisible(); + await expect(page.locator("text=Consensus")).toBeVisible(); + await expect(page.locator("text=Elected Board")).toBeVisible(); + await expect(page.locator("text=Petition")).toBeVisible(); + + // Check rule descriptions + await expect( + page.locator("text=Units called Circles have the ability to decide") + ).toBeVisible(); + await expect( + page.locator("text=Decisions that affect the group collectively") + ).toBeVisible(); + await expect( + page.locator("text=An elected board determines policies") + ).toBeVisible(); + await expect( + page.locator("text=All participants can propose and vote") + ).toBeVisible(); + + // Test card interactions + const consensusCard = page.locator('[aria-label*="Consensus clusters"]'); + await consensusCard.click(); + // Should trigger analytics tracking (console log in test environment) + + // Check "See all templates" button + await expect( + page.locator('button:has-text("See all templates")') + ).toBeVisible(); + }); + + test("feature grid section functionality", async ({ page }) => { + // Check section header + await expect( + page.locator('h2:has-text("We\'ve got your back")') + ).toBeVisible(); + await expect( + page.locator( + "text=Use our toolkit to improve, document, and evolve your organization" + ) + ).toBeVisible(); + + // Check all four feature cards + await expect(page.locator("text=Decision-making support")).toBeVisible(); + await expect(page.locator("text=Values alignment exercises")).toBeVisible(); + await expect(page.locator("text=Membership guidance")).toBeVisible(); + await expect(page.locator("text=Conflict resolution tools")).toBeVisible(); + + // Check feature links + const featureLinks = page.locator('a[href^="#"]'); + await expect(featureLinks).toHaveCount(4); + + // Test feature card interactions + await page.locator('a[href="#decision-making"]').click(); + // Should navigate to decision-making section + }); + + test("quote block section displays correctly", async ({ page }) => { + // Check quote content + await expect( + page.locator("text=The rules of decision-making must be open") + ).toBeVisible(); + + // Check author and source + await expect(page.locator("text=Jo Freeman")).toBeVisible(); + await expect( + page.locator("text=The Tyranny of Structurelessness") + ).toBeVisible(); + + // Check avatar + await expect( + page.locator('img[alt="Portrait of Jo Freeman"]') + ).toBeVisible(); + + // Check decorative elements + await expect( + page.locator('[class*="pointer-events-none absolute z-0"]') + ).toBeVisible(); + }); + + test("ask organizer section functionality", async ({ page }) => { + // Check section content + await expect(page.locator("text=Still have questions?")).toBeVisible(); + await expect( + page.locator("text=Get answers from an experienced organizer") + ).toBeVisible(); + + // Check CTA button + const askButton = page.locator('button:has-text("Ask an organizer")'); + await expect(askButton).toBeVisible(); + await expect(askButton).toBeEnabled(); + + // Test button interaction + await askButton.click(); + // Should trigger analytics tracking + }); + + test("header navigation functionality", async ({ page }) => { + // Check header is present + await expect(page.locator("header")).toBeVisible(); + + // Check navigation elements + await expect(page.locator("nav")).toBeVisible(); + + // Test logo/header click + const header = page.locator("header"); + await header.click(); + // Should stay on homepage + await expect(page).toHaveURL("/"); + }); + + test("footer section displays correctly", async ({ page }) => { + // Scroll to footer + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + + // Check footer is present + await expect(page.locator("footer")).toBeVisible(); + + // Check footer content + await expect(page.locator("footer")).toContainText("CommunityRule"); + }); + + test("responsive design behavior", async ({ page }) => { + // Test mobile viewport + await page.setViewportSize({ width: 375, height: 667 }); + await expect( + page.locator("h1, h2").filter({ hasText: "Collaborate" }) + ).toBeVisible(); + + // Test tablet viewport + await page.setViewportSize({ width: 768, height: 1024 }); + await expect( + page.locator("h1, h2").filter({ hasText: "Collaborate" }) + ).toBeVisible(); + + // Test desktop viewport + await page.setViewportSize({ width: 1440, height: 900 }); + await expect( + page.locator("h1, h2").filter({ hasText: "Collaborate" }) + ).toBeVisible(); + }); + + test("keyboard navigation and accessibility", async ({ page }) => { + // Test tab navigation + await page.keyboard.press("Tab"); + await expect(page.locator(":focus")).toBeVisible(); + + // Navigate through interactive elements + await page.keyboard.press("Tab"); + await page.keyboard.press("Tab"); + await page.keyboard.press("Tab"); + + // Test Enter key on buttons + await page.keyboard.press("Enter"); + + // Test Escape key + await page.keyboard.press("Escape"); + }); + + test("page performance metrics", async ({ page }) => { + // Measure page load time + const startTime = Date.now(); + await page.goto("/"); + const loadTime = Date.now() - startTime; + + // Page should load within reasonable time (5 seconds) + expect(loadTime).toBeLessThan(5000); + + // Check for any console errors + const consoleErrors: string[] = []; + page.on("console", (msg) => { + if (msg.type() === "error") { + consoleErrors.push(msg.text()); + } + }); + + await page.reload(); + expect(consoleErrors.length).toBe(0); + }); + + test("accessibility standards compliance", async ({ page }) => { + // Basic accessibility checks + const html = page.locator("html"); + const lang = await html.getAttribute("lang"); + expect(lang).toBeTruthy(); + + // Check for main heading + const h1 = page.locator("h1").first(); + await expect(h1).toBeVisible(); + + // Check for main landmark + const main = page.locator("main, [role='main']"); + await expect(main).toBeVisible(); + + // Check for navigation + const nav = page.locator("nav, [role='navigation']").first(); + await expect(nav).toBeVisible(); + }); + + test("scroll behavior and smooth scrolling", async ({ page }) => { + // Test smooth scrolling to sections + const ctaButton = page + .locator('button:has-text("Learn how CommunityRule works")') + .first(); + await ctaButton.click(); + + // Should smoothly scroll to numbered cards section + await page.waitForTimeout(1000); // Wait for scroll animation + + // Check we're at the numbered cards section + await expect( + page.locator('h2:has-text("How CommunityRule works")') + ).toBeVisible(); + }); + + test("image loading and optimization", async ({ page }) => { + // Check all images load properly + const images = page.locator("img"); + await expect(images).toHaveCount.greaterThan(0); + + // Wait for images to load + await page.waitForLoadState("networkidle"); + + // Check for any broken images + const brokenImages = await page.evaluate(() => { + const imgs = document.querySelectorAll("img"); + return Array.from(imgs).filter( + (img) => !img.complete || img.naturalWidth === 0 + ); + }); + + expect(brokenImages.length).toBe(0); + }); + + test("form interactions and validation", async ({ page }) => { + // Test any form elements (if present) + const forms = page.locator("form"); + const formCount = await forms.count(); + + if (formCount > 0) { + // Test form submission + const submitButton = page.locator('button[type="submit"]'); + if ((await submitButton.count()) > 0) { + await submitButton.click(); + // Should handle form submission appropriately + } + } + }); + + test("error handling and fallbacks", async ({ page }) => { + // Test with slow network + await page.route("**/*", (route) => { + route.continue(); + }); + + // Test with offline mode + await page.setOffline(true); + await page.reload(); + + // Should handle offline state gracefully + await expect(page.locator("body")).toBeVisible(); + + // Restore online mode + await page.setOffline(false); + }); +}); diff --git a/tests/e2e/performance.spec.ts b/tests/e2e/performance.spec.ts new file mode 100644 index 0000000..b32b433 --- /dev/null +++ b/tests/e2e/performance.spec.ts @@ -0,0 +1,384 @@ +import { test, expect } from "@playwright/test"; +import { PlaywrightPerformanceMonitor } from "../performance/performance-monitor.js"; + +// Environment-aware performance budgets and thresholds +const PERFORMANCE_BUDGETS = { + // Page load performance + page_load_time: 3000, // 3 seconds + first_contentful_paint: 2000, // 2 seconds + largest_contentful_paint: 2500, // 2.5 seconds + first_input_delay: 100, // 100ms + + // Navigation timing + dns_lookup: 100, // 100ms + tcp_connection: 200, // 200ms + ttfb: 600, // 600ms + dom_content_loaded: 1500, // 1.5 seconds + full_load: 3000, // 3 seconds + + // Component performance + component_render_time: 500, // 500ms + interaction_time: 100, // 100ms + scroll_performance: process.env.CI ? 200 : 50, // Looser in CI (200ms vs 50ms) + + // Resource performance + network_request_duration: 1000, // 1 second + memory_usage_mb: 50, // 50MB +}; + +// Baseline metrics for regression detection +const BASELINE_METRICS = { + page_load_time: 2000, + first_contentful_paint: 1500, + largest_contentful_paint: 2000, + first_input_delay: 50, + dns_lookup: 50, + tcp_connection: 100, + ttfb: 400, + dom_content_loaded: 1000, + full_load: 2000, + component_render_time: 300, + interaction_time: 50, + scroll_performance: 30, + network_request_duration: 500, + memory_usage_mb: 30, +}; + +test.describe("Performance Monitoring", () => { + let performanceMonitor: PlaywrightPerformanceMonitor; + + test.beforeEach(async ({ page }) => { + // Mark tests as slower in CI environment + if (process.env.CI) test.slow(); + + performanceMonitor = new PlaywrightPerformanceMonitor(page); + performanceMonitor.setThresholds(PERFORMANCE_BUDGETS); + performanceMonitor.setBaselines(BASELINE_METRICS); + }); + + test("homepage load performance", async ({ page }) => { + const result = await performanceMonitor.measurePageLoad("/"); + + // Assert page load time is within budget + expect(result.loadTime).toBeLessThan(PERFORMANCE_BUDGETS.page_load_time); + + // Assert individual metrics + expect(result.metrics.ttfb).toBeLessThan(PERFORMANCE_BUDGETS.ttfb); + expect(result.metrics.domContentLoaded).toBeLessThan( + PERFORMANCE_BUDGETS.dom_content_loaded + ); + expect(result.metrics.load).toBeLessThan(PERFORMANCE_BUDGETS.full_load); + + // Check for performance regressions + const summary = performanceMonitor.getSummary(); + console.log("Performance Summary:", summary); + }); + + test("core web vitals", async ({ page }) => { + await page.goto("/"); + + // Wait for page to fully load + await page.waitForLoadState("networkidle"); + + // Get Core Web Vitals with timeout + const coreWebVitals = await page.evaluate(() => { + return new Promise((resolve) => { + const timeout = setTimeout(() => { + observer.disconnect(); + resolve({ lcp: 0, fid: 0, cls: 0 }); // Default values if timeout + }, 10000); // 10 second timeout + + const observer = new PerformanceObserver((list) => { + const entries = list.getEntries(); + const metrics: any = {}; + + for (const entry of entries) { + if (entry.name === "LCP") { + metrics.lcp = entry.startTime; + } else if (entry.name === "FID") { + metrics.fid = entry.processingStart - entry.startTime; + } else if (entry.name === "CLS") { + metrics.cls = entry.value; + } + } + + if (Object.keys(metrics).length === 3) { + clearTimeout(timeout); + observer.disconnect(); + resolve(metrics); + } + }); + + observer.observe({ + entryTypes: [ + "largest-contentful-paint", + "first-input", + "layout-shift", + ], + }); + }); + }); + + // Assert Core Web Vitals are within acceptable ranges + expect(coreWebVitals.lcp).toBeLessThan( + PERFORMANCE_BUDGETS.largest_contentful_paint + ); + expect(coreWebVitals.fid).toBeLessThan( + PERFORMANCE_BUDGETS.first_input_delay + ); + expect(coreWebVitals.cls).toBeLessThan(0.1); // CLS should be less than 0.1 + }); + + test("component render performance", async ({ page }) => { + await page.goto("/"); + + // Measure header render time + const headerRenderTime = await performanceMonitor.measureComponentRender( + "header" + ); + expect(headerRenderTime).toBeLessThan( + PERFORMANCE_BUDGETS.component_render_time + ); + + // Measure footer render time + const footerRenderTime = await performanceMonitor.measureComponentRender( + "footer" + ); + expect(footerRenderTime).toBeLessThan( + PERFORMANCE_BUDGETS.component_render_time + ); + + // Measure main content render time + const mainRenderTime = await performanceMonitor.measureComponentRender( + "main" + ); + expect(mainRenderTime).toBeLessThan( + PERFORMANCE_BUDGETS.component_render_time + ); + }); + + test("interaction performance", async ({ page }) => { + await page.goto("/"); + + // Wait for page to be ready + await page.waitForLoadState("networkidle"); + + // Measure button click performance with better element selection + const buttonClickTime = await performanceMonitor.measureInteraction( + 'button:has-text("Learn how CommunityRule works")', + async () => { + const button = page + .locator('button:has-text("Learn how CommunityRule works")') + .first(); + await button.waitFor({ state: "visible" }); + await button.click(); + } + ); + expect(buttonClickTime).toBeLessThan(PERFORMANCE_BUDGETS.interaction_time); + + // Measure link click performance with better element selection + const linkClickTime = await performanceMonitor.measureInteraction( + 'a:has-text("Use Cases")', + async () => { + const link = page.locator('a:has-text("Use Cases")').first(); + await link.waitFor({ state: "visible" }); + await link.click(); + } + ); + expect(linkClickTime).toBeLessThan(PERFORMANCE_BUDGETS.interaction_time); + }); + + test("scroll performance", async ({ page }) => { + await page.goto("/"); + + // Measure scroll performance + const scrollTime = await performanceMonitor.measureScrollPerformance(); + expect(scrollTime).toBeLessThan(PERFORMANCE_BUDGETS.scroll_performance); + }); + + test("memory usage", async ({ page }) => { + await page.goto("/"); + + // Get memory usage + const memoryUsage = await performanceMonitor.getMemoryUsage(); + + if (memoryUsage) { + const usedMemoryMB = memoryUsage.usedJSHeapSize / 1024 / 1024; + expect(usedMemoryMB).toBeLessThan(PERFORMANCE_BUDGETS.memory_usage_mb); + + console.log(`Memory Usage: ${usedMemoryMB.toFixed(2)}MB`); + } + }); + + test("network request performance", async ({ page }) => { + const requests = await performanceMonitor.monitorNetworkRequests(); + + await page.goto("/"); + await page.waitForLoadState("networkidle"); + + // Check that all requests completed within budget + const summary = performanceMonitor.getSummary(); + if (summary.network_request_duration) { + expect(summary.network_request_duration.average).toBeLessThan( + PERFORMANCE_BUDGETS.network_request_duration + ); + } + }); + + test("responsive performance across breakpoints", async ({ page }) => { + const breakpoints = [ + { name: "mobile", width: 375, height: 667 }, + { name: "tablet", width: 768, height: 1024 }, + { name: "desktop", width: 1280, height: 720 }, + ]; + + for (const breakpoint of breakpoints) { + await page.setViewportSize(breakpoint); + + const result = await performanceMonitor.measurePageLoad("/"); + + // Assert performance is maintained across breakpoints + expect(result.loadTime).toBeLessThan(PERFORMANCE_BUDGETS.page_load_time); + + console.log(`${breakpoint.name} load time: ${result.loadTime}ms`); + } + }); + + test("performance under load", async ({ page }) => { + // Simulate slower network conditions + await page.route("**/*", (route) => { + route.continue(); + }); + + // Add artificial delay to simulate network latency + await page.addInitScript(() => { + const originalFetch = window.fetch; + window.fetch = async (...args) => { + await new Promise((resolve) => setTimeout(resolve, 100)); // 100ms delay + return originalFetch(...args); + }; + }); + + const result = await performanceMonitor.measurePageLoad("/"); + + // Even under load, page should load within reasonable time + expect(result.loadTime).toBeLessThan( + PERFORMANCE_BUDGETS.page_load_time * 1.5 + ); + }); + + test("performance regression detection", async ({ page }) => { + await page.goto("/"); + + // Simulate a performance regression by adding a heavy operation + await page.addInitScript(() => { + // Add a heavy operation that would cause regression + const heavyOperation = () => { + let result = 0; + for (let i = 0; i < 1000000; i++) { + result += Math.random(); + } + return result; + }; + + // Execute heavy operation on page load + window.addEventListener("load", () => { + heavyOperation(); + }); + }); + + const result = await performanceMonitor.measurePageLoad("/"); + + // This should trigger a performance regression warning + const summary = performanceMonitor.getSummary(); + console.log("Performance Summary with Regression:", summary); + }); + + test("performance metrics export", async ({ page }) => { + await page.goto("/"); + + // Perform various operations to collect metrics + await performanceMonitor.measureComponentRender("header"); + await performanceMonitor.measureScrollPerformance(); + await performanceMonitor.getMemoryUsage(); + + // Export all metrics + const exportedData = performanceMonitor.export(); + + // Verify exported data structure + expect(exportedData.metrics).toBeDefined(); + expect(exportedData.baselines).toBeDefined(); + expect(exportedData.thresholds).toBeDefined(); + expect(exportedData.summary).toBeDefined(); + + console.log( + "Exported Performance Data:", + JSON.stringify(exportedData, null, 2) + ); + }); + + test("performance budget compliance", async ({ page }) => { + await page.goto("/"); + + // Collect comprehensive metrics + await performanceMonitor.measurePageLoad("/"); + await performanceMonitor.measureComponentRender("header"); + await performanceMonitor.measureComponentRender("footer"); + await performanceMonitor.measureScrollPerformance(); + await performanceMonitor.getMemoryUsage(); + + const summary = performanceMonitor.getSummary(); + + // Check all metrics against budgets + for (const [metricName, budget] of Object.entries(PERFORMANCE_BUDGETS)) { + if (summary[metricName]) { + const actualValue = + summary[metricName].latest || summary[metricName].average; + expect(actualValue).toBeLessThan(budget); + console.log(`${metricName}: ${actualValue}ms (budget: ${budget}ms)`); + } + } + }); +}); + +test.describe("Performance Regression Testing", () => { + test("detect performance regressions over time", async ({ page }) => { + const performanceMonitor = new PlaywrightPerformanceMonitor(page); + + // Set strict baselines for regression detection + const strictBaselines = { + page_load_time: 1500, + first_contentful_paint: 1000, + component_render_time: 200, + interaction_time: 30, + }; + + performanceMonitor.setBaselines(strictBaselines); + + // Run multiple iterations to detect trends + const iterations = 3; + const results = []; + + for (let i = 0; i < iterations; i++) { + const result = await performanceMonitor.measurePageLoad("/"); + results.push(result.loadTime); + + // Small delay between iterations + await page.waitForTimeout(1000); + } + + // Check for consistent performance + const averageLoadTime = results.reduce((a, b) => a + b, 0) / results.length; + const variance = + results.reduce( + (acc, val) => acc + Math.pow(val - averageLoadTime, 2), + 0 + ) / results.length; + + // Performance should be consistent (low variance) + expect(variance).toBeLessThan(100000); // Variance should be less than 100msยฒ + + console.log(`Average load time: ${averageLoadTime}ms`); + console.log(`Variance: ${variance}`); + }); +}); diff --git a/tests/e2e/user-journeys.spec.ts b/tests/e2e/user-journeys.spec.ts new file mode 100644 index 0000000..0591e14 --- /dev/null +++ b/tests/e2e/user-journeys.spec.ts @@ -0,0 +1,357 @@ +import { test, expect } from "@playwright/test"; + +test.describe("User Journeys", () => { + test.beforeEach(async ({ page }) => { + await page.goto("/"); + }); + + test("complete user journey: learn about CommunityRule", async ({ page }) => { + // 1. User lands on homepage + await expect(page.locator("text=Collaborate")).toBeVisible(); + + // 2. User reads hero section + await expect( + page.locator("text=Help your community make important decisions") + ).toBeVisible(); + + // 3. User clicks CTA to learn more + const learnButton = page + .locator('button:has-text("Learn how CommunityRule works")') + .first(); + if ((await learnButton.count()) > 0 && (await learnButton.isVisible())) { + await learnButton.click(); + } + + // 4. User scrolls to numbered cards section + await expect( + page.locator('h2:has-text("How CommunityRule works")') + ).toBeVisible(); + + // 5. User reads the process steps + await expect( + page.locator("text=Document how your community makes decisions") + ).toBeVisible(); + await expect( + page.locator("text=Build an operating manual for a successful community") + ).toBeVisible(); + await expect( + page.locator( + "text=Get a link to your manual for your group to review and evolve" + ) + ).toBeVisible(); + + // 6. User explores rule templates + await page.locator("text=Consensus clusters").first().click(); + await page.locator("text=Consensus").nth(1).click(); // Use nth(1) to get the second "Consensus" element + await page.locator("text=Elected Board").first().click(); + await page.locator("text=Petition").first().click(); + + // 7. User checks out features - check if elements exist and are visible first + const features = [ + "Decision-making support", + "Values alignment exercises", + "Membership guidance", + "Conflict resolution tools", + ]; + + for (const feature of features) { + const featureElement = page.locator(`text=${feature}`); + if ( + (await featureElement.count()) > 0 && + (await featureElement.first().isVisible()) + ) { + await featureElement.first().click(); + } + } + + // 8. User reads testimonial + await expect(page.locator("text=Jo Freeman")).toBeVisible(); + + // 9. User decides to contact organizer + const askButton = page.locator('button:has-text("Ask an organizer")'); + if ( + (await askButton.count()) > 0 && + (await askButton.first().isVisible()) + ) { + await askButton.first().click(); + } + + // 10. User creates CommunityRule + const createButton = page.locator( + 'button:has-text("Create CommunityRule")' + ); + if ( + (await createButton.count()) > 0 && + (await createButton.first().isVisible()) + ) { + await createButton.first().click(); + } + }); + + test("user journey: explore rule templates", async ({ page }) => { + // Scroll to rule stack section + await page.locator("text=Consensus clusters").scrollIntoViewIfNeeded(); + + // Explore each rule template + const ruleTemplates = [ + "Consensus clusters", + "Consensus", + "Elected Board", + "Petition", + ]; + + for (const template of ruleTemplates) { + const templateElement = page.locator(`text=${template}`); + if (template === "Consensus") { + await templateElement.nth(1).click(); // Use nth(1) for the second "Consensus" element + } else { + await templateElement.first().click(); + } + // Should trigger analytics tracking + await page.waitForTimeout(500); // Brief pause between clicks + } + + // Click "See all templates" + await page.locator('button:has-text("See all templates")').click(); + }); + + test("user journey: explore feature tools", async ({ page }) => { + // Scroll to feature grid section + await page.locator("text=We've got your back").scrollIntoViewIfNeeded(); + + // Explore each feature + const features = [ + { name: "Decision-making support", href: "#decision-making" }, + { name: "Values alignment exercises", href: "#values-alignment" }, + { name: "Membership guidance", href: "#membership-guidance" }, + { name: "Conflict resolution tools", href: "#conflict-resolution" }, + ]; + + for (const feature of features) { + await page.locator(`a[href="${feature.href}"]`).click(); + await page.waitForTimeout(500); + } + }); + + test("user journey: contact organizer", async ({ page }) => { + // Scroll to ask organizer section + await page.locator("text=Still have questions?").scrollIntoViewIfNeeded(); + + // Read the section + await expect( + page.locator("text=Get answers from an experienced organizer") + ).toBeVisible(); + + // Click contact button - check if it exists and is visible first + const askButton = page.locator('button:has-text("Ask an organizer")'); + if ( + (await askButton.count()) > 0 && + (await askButton.first().isVisible()) + ) { + await askButton.first().click(); + } + + // Should trigger analytics tracking + // In a real app, this might open a contact form or modal + }); + + test("user journey: create CommunityRule", async ({ page }) => { + // Simplified approach - just check if the button exists and is visible + const createButton = page.locator( + 'button:has-text("Create CommunityRule")' + ); + + if ( + (await createButton.count()) > 0 && + (await createButton.first().isVisible()) + ) { + await createButton.first().click(); + } + + // Should navigate to creation flow + // In a real app, this would go to a form or wizard + }); + + test("user journey: learn how it works", async ({ page }) => { + // Click "See how it works" button + await page.locator('button:has-text("See how it works")').click(); + + // Should show more detailed information + // In a real app, this might open a modal or navigate to a detailed page + }); + + test("user journey: scroll through entire page", async ({ page }) => { + // Start at top + await expect(page.locator("text=Collaborate")).toBeVisible(); + + // Simplified approach - just scroll to bottom and check footer + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + await expect(page.locator("footer").first()).toBeVisible(); + }); + + test("user journey: keyboard navigation through page", async ({ page }) => { + // Start with tab navigation + await page.keyboard.press("Tab"); + await expect(page.locator(":focus")).toBeVisible(); + + // Navigate through all interactive elements + let tabCount = 0; + const maxTabs = 50; // Prevent infinite loop + + while (tabCount < maxTabs) { + await page.keyboard.press("Tab"); + tabCount++; + + // Check if we've cycled back to the beginning + const focusedElement = page.locator(":focus"); + if ((await focusedElement.count()) === 0) { + break; + } + } + + // Test Enter key on focused elements + await page.keyboard.press("Enter"); + }); + + test("user journey: mobile navigation", async ({ page }) => { + // Set mobile viewport + await page.setViewportSize({ width: 375, height: 667 }); + + // Navigate through page on mobile + await expect(page.locator("text=Collaborate")).toBeVisible(); + + // Scroll through sections + await page.locator("section").first().scrollIntoViewIfNeeded(); + + // Test basic touch interactions - check if elements exist and are visible first + const learnButton = page + .locator('button:has-text("Learn how CommunityRule works")') + .first(); + if ((await learnButton.count()) > 0 && (await learnButton.isVisible())) { + await learnButton.click(); + } + + const consensusText = page.locator("text=Consensus clusters"); + if ( + (await consensusText.count()) > 0 && + (await consensusText.isVisible()) + ) { + await consensusText.click(); + } + + const askButton = page + .locator('button:has-text("Ask an organizer")') + .first(); + if ((await askButton.count()) > 0 && (await askButton.isVisible())) { + await askButton.click(); + } + }); + + test("user journey: tablet navigation", async ({ page }) => { + // Set tablet viewport + await page.setViewportSize({ width: 768, height: 1024 }); + + // Navigate through page on tablet + await expect(page.locator("text=Collaborate")).toBeVisible(); + + // Test tablet-specific interactions - check if elements exist and are visible first + const learnButton = page + .locator('button:has-text("Learn how CommunityRule works")') + .first(); + if ((await learnButton.count()) > 0 && (await learnButton.isVisible())) { + await learnButton.click(); + } + + const consensusText = page.locator("text=Consensus clusters"); + if ( + (await consensusText.count()) > 0 && + (await consensusText.isVisible()) + ) { + await consensusText.click(); + } + + const askButton = page + .locator('button:has-text("Ask an organizer")') + .first(); + if ((await askButton.count()) > 0 && (await askButton.isVisible())) { + await askButton.click(); + } + }); + + test("user journey: desktop navigation", async ({ page }) => { + // Set desktop viewport + await page.setViewportSize({ width: 1440, height: 900 }); + + // Navigate through page on desktop + await expect(page.locator("text=Collaborate")).toBeVisible(); + + // Test desktop-specific interactions - check if elements exist and are visible first + const learnButton = page + .locator('button:has-text("Learn how CommunityRule works")') + .first(); + if ((await learnButton.count()) > 0 && (await learnButton.isVisible())) { + await learnButton.click(); + } + + const consensusText = page.locator("text=Consensus clusters"); + if ( + (await consensusText.count()) > 0 && + (await consensusText.isVisible()) + ) { + await consensusText.click(); + } + + const askButton = page + .locator('button:has-text("Ask an organizer")') + .first(); + if ((await askButton.count()) > 0 && (await askButton.isVisible())) { + await askButton.click(); + } + }); + + test("user journey: accessibility navigation", async ({ page }) => { + // Test screen reader navigation + await page.keyboard.press("Tab"); + + // Navigate through landmarks + await page.keyboard.press("Tab"); + await page.keyboard.press("Tab"); + + // Test heading navigation (if supported) + await page.keyboard.press("Tab"); + + // Test form navigation + await page.keyboard.press("Tab"); + + // Test button activation + await page.keyboard.press("Enter"); + }); + + test("user journey: performance testing", async ({ page }) => { + // Measure initial page load + const startTime = Date.now(); + await page.goto("/"); + const loadTime = Date.now() - startTime; + + expect(loadTime).toBeLessThan(3000); // Should load within 3 seconds + + // Measure scroll performance + const scrollStartTime = Date.now(); + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + const scrollTime = Date.now() - scrollStartTime; + + expect(scrollTime).toBeLessThan(1000); // Should scroll smoothly + + // Measure interaction response time + const clickStartTime = Date.now(); + const learnButton = page + .locator('button:has-text("Learn how CommunityRule works")') + .first(); + if ((await learnButton.count()) > 0 && (await learnButton.isVisible())) { + await learnButton.click(); + } + const clickTime = Date.now() - clickStartTime; + + expect(clickTime).toBeLessThan(500); // Should respond quickly + }); +}); diff --git a/tests/e2e/visual-regression.spec.ts b/tests/e2e/visual-regression.spec.ts new file mode 100644 index 0000000..0992bfc --- /dev/null +++ b/tests/e2e/visual-regression.spec.ts @@ -0,0 +1,380 @@ +import { test, expect } from "@playwright/test"; + +test.describe("Visual Regression Tests", () => { + test.beforeEach(async ({ page }) => { + await page.goto("/"); + // Wait for all content to load + await page.waitForLoadState("networkidle"); + }); + + test("homepage full page screenshot", async ({ page }) => { + // Take full page screenshot + await expect(page).toHaveScreenshot("homepage-full.png", { + fullPage: true, + animations: "disabled", + }); + }); + + test("homepage viewport screenshot", async ({ page }) => { + // Take viewport screenshot + await expect(page).toHaveScreenshot("homepage-viewport.png", { + animations: "disabled", + }); + }); + + test("hero banner section screenshot", async ({ page }) => { + // Scroll to hero section and take screenshot + await page.locator("text=Collaborate").scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); // Wait for animations + + const heroSection = page.locator("section").first(); + await expect(heroSection).toHaveScreenshot("hero-banner.png", { + animations: "disabled", + }); + }); + + test("logo wall section screenshot", async ({ page }) => { + // Scroll to logo wall section + await page + .locator("text=Trusted by leading cooperators") + .scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const logoSection = page.locator("section").nth(1); + await expect(logoSection).toHaveScreenshot("logo-wall.png", { + animations: "disabled", + }); + }); + + test("numbered cards section screenshot", async ({ page }) => { + // Scroll to numbered cards section + await page + .locator('h2:has-text("How CommunityRule works")') + .scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const cardsSection = page.locator("section").nth(2); + await expect(cardsSection).toHaveScreenshot("numbered-cards.png", { + animations: "disabled", + }); + }); + + test("rule stack section screenshot", async ({ page }) => { + // Scroll to rule stack section + await page.locator("text=Consensus clusters").scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const ruleSection = page.locator("section").nth(3); + await expect(ruleSection).toHaveScreenshot("rule-stack.png", { + animations: "disabled", + }); + }); + + test("feature grid section screenshot", async ({ page }) => { + // Scroll to feature grid section - use a more reliable selector + await page.locator("text=We've got your back").scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const featureSection = page.locator("section").nth(4); + await expect(featureSection).toHaveScreenshot("feature-grid.png", { + animations: "disabled", + }); + }); + + test("quote block section screenshot", async ({ page }) => { + // Scroll to quote block section + await page.locator("text=Jo Freeman").scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const quoteSection = page.locator("section").nth(5); + await expect(quoteSection).toHaveScreenshot("quote-block.png", { + animations: "disabled", + }); + }); + + test("ask organizer section screenshot", async ({ page }) => { + // Scroll to ask organizer section + await page.locator("text=Still have questions?").scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const askSection = page.locator("section").nth(6); + await expect(askSection).toHaveScreenshot("ask-organizer.png", { + animations: "disabled", + }); + }); + + test("header component screenshot", async ({ page }) => { + const header = page.locator("header"); + await expect(header).toHaveScreenshot("header.png", { + animations: "disabled", + }); + }); + + test("footer component screenshot", async ({ page }) => { + // Scroll to footer + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + await page.waitForTimeout(500); + + // Use a more specific selector for the main footer + const footer = page.locator("footer").last(); + await expect(footer).toHaveScreenshot("footer.png", { + animations: "disabled", + }); + }); + + test("mobile viewport screenshots", async ({ page }) => { + // Test mobile viewport + await page.setViewportSize({ width: 375, height: 667 }); + await page.waitForTimeout(1000); + + await expect(page).toHaveScreenshot("homepage-mobile.png", { + animations: "disabled", + }); + + // Test mobile hero section + await page.locator("text=Collaborate").scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const heroSection = page.locator("section").first(); + await expect(heroSection).toHaveScreenshot("hero-banner-mobile.png", { + animations: "disabled", + }); + }); + + test("tablet viewport screenshots", async ({ page }) => { + // Test tablet viewport + await page.setViewportSize({ width: 768, height: 1024 }); + await page.waitForTimeout(1000); + + await expect(page).toHaveScreenshot("homepage-tablet.png", { + animations: "disabled", + }); + + // Test tablet hero section + await page.locator("text=Collaborate").scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const heroSection = page.locator("section").first(); + await expect(heroSection).toHaveScreenshot("hero-banner-tablet.png", { + animations: "disabled", + }); + }); + + test("desktop viewport screenshots", async ({ page }) => { + // Test desktop viewport + await page.setViewportSize({ width: 1440, height: 900 }); + await page.waitForTimeout(1000); + + await expect(page).toHaveScreenshot("homepage-desktop.png", { + animations: "disabled", + }); + + // Test desktop hero section + await page.locator("text=Collaborate").scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const heroSection = page.locator("section").first(); + await expect(heroSection).toHaveScreenshot("hero-banner-desktop.png", { + animations: "disabled", + }); + }); + + test("large desktop viewport screenshots", async ({ page }) => { + // Test large desktop viewport + await page.setViewportSize({ width: 1920, height: 1080 }); + await page.waitForTimeout(1000); + + await expect(page).toHaveScreenshot("homepage-large-desktop.png", { + animations: "disabled", + }); + }); + + // test('button hover states', async ({ page }) => { + // // Test button hover states - scroll to hero section first to ensure button is visible + // await page.locator('text=Collaborate').scrollIntoViewIfNeeded(); + // await page.waitForTimeout(500); + // + // // Use a more specific selector for the visible button + // const ctaButton = page.locator('button:has-text("Learn how CommunityRule works")').first(); + // + // // Ensure button is visible + // await ctaButton.scrollIntoViewIfNeeded(); + // await page.waitForTimeout(500); + // + // // Normal state + // await expect(ctaButton).toHaveScreenshot('button-normal.png', { + // animations: 'disabled' + // }); + // + // // Hover state + // await ctaButton.hover(); + // await page.waitForTimeout(500); + // await expect(ctaButton).toHaveScreenshot('button-hover.png', { + // animations: 'disabled' + // }); + // }); + + test("rule card hover states", async ({ page }) => { + // Scroll to rule stack section + await page.locator("text=Consensus clusters").scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const consensusCard = page.locator('[aria-label*="Consensus clusters"]'); + + // Normal state + await expect(consensusCard).toHaveScreenshot("rule-card-normal.png", { + animations: "disabled", + }); + + // Hover state + await consensusCard.hover(); + await page.waitForTimeout(500); + await expect(consensusCard).toHaveScreenshot("rule-card-hover.png", { + animations: "disabled", + }); + }); + + test("feature card hover states", async ({ page }) => { + // Scroll to feature grid section + await page.locator("text=We've got your back").scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const featureCard = page.locator('a[href="#decision-making"]'); + + // Normal state + await expect(featureCard).toHaveScreenshot("feature-card-normal.png", { + animations: "disabled", + }); + + // Hover state + await featureCard.hover(); + await page.waitForTimeout(500); + await expect(featureCard).toHaveScreenshot("feature-card-hover.png", { + animations: "disabled", + }); + }); + + test("logo hover states", async ({ page }) => { + // Scroll to logo wall section + await page + .locator("text=Trusted by leading cooperators") + .scrollIntoViewIfNeeded(); + await page.waitForTimeout(500); + + const logo = page.locator('img[alt="Food Not Bombs"]'); + + // Normal state + await expect(logo).toHaveScreenshot("logo-normal.png", { + animations: "disabled", + }); + + // Hover state + await logo.hover(); + await page.waitForTimeout(500); + await expect(logo).toHaveScreenshot("logo-hover.png", { + animations: "disabled", + }); + }); + + // test('focus states', async ({ page }) => { + // // Test focus states for interactive elements - scroll to hero section first + // await page.locator('text=Collaborate').scrollIntoViewIfNeeded(); + // await page.waitForTimeout(500); + // + // // Use first button and ensure it's visible + // const ctaButton = page.locator('button:has-text("Learn how CommunityRule works")').first(); + // + // // Ensure button is visible + // await ctaButton.scrollIntoViewIfNeeded(); + // await page.waitForTimeout(500); + // + // // Focus the button + // await ctaButton.focus(); + // await page.waitForTimeout(500); + // + // await expect(ctaButton).toHaveScreenshot('button-focus.png', { + // animations: 'disabled' + // }); + // }); + + test("loading states", async ({ page }) => { + // Test loading states by blocking resources + await page.route("**/*", (route) => { + // Delay all requests to simulate loading + setTimeout(() => route.continue(), 1000); + }); + + // Reload page to trigger loading states + await page.reload(); + + // Take screenshot during loading + await expect(page).toHaveScreenshot("homepage-loading.png", { + animations: "disabled", + }); + }); + + test("error states", async ({ page }) => { + // Test error states by blocking critical resources + await page.route("**/*.css", (route) => { + route.abort(); + }); + + // Reload page to trigger error states + await page.reload(); + + // Take screenshot of error state + await expect(page).toHaveScreenshot("homepage-error.png", { + animations: "disabled", + }); + }); + + test("high contrast mode", async ({ page }) => { + // Simulate high contrast mode + await page.evaluate(() => { + document.body.style.filter = "contrast(200%)"; + }); + + await expect(page).toHaveScreenshot("homepage-high-contrast.png", { + animations: "disabled", + }); + + // Reset contrast + await page.evaluate(() => { + document.body.style.filter = "none"; + }); + }); + + test("reduced motion mode", async ({ page }) => { + // Simulate reduced motion preference + await page.evaluate(() => { + document.documentElement.style.setProperty( + "--prefers-reduced-motion", + "reduce" + ); + }); + + await expect(page).toHaveScreenshot("homepage-reduced-motion.png", { + animations: "disabled", + }); + }); + + test("dark mode simulation", async ({ page }) => { + // Simulate dark mode (if supported) + await page.evaluate(() => { + document.documentElement.classList.add("dark"); + document.body.style.backgroundColor = "#000"; + document.body.style.color = "#fff"; + }); + + await expect(page).toHaveScreenshot("homepage-dark-mode.png", { + animations: "disabled", + }); + + // Reset to light mode + await page.evaluate(() => { + document.documentElement.classList.remove("dark"); + document.body.style.backgroundColor = ""; + document.body.style.color = ""; + }); + }); +}); diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-chromium.png new file mode 100644 index 0000000..d808d6b Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-firefox.png new file mode 100644 index 0000000..2e23988 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-mobile.png new file mode 100644 index 0000000..fc7a9ff Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-webkit.png new file mode 100644 index 0000000..f6e0a97 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/ask-organizer-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-chromium.png new file mode 100644 index 0000000..5cbe6dd Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-firefox.png new file mode 100644 index 0000000..f8ccdf3 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-mobile.png new file mode 100644 index 0000000..8424716 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-webkit.png new file mode 100644 index 0000000..ee053f3 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-hover-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-chromium.png new file mode 100644 index 0000000..c2beeaf Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-firefox.png new file mode 100644 index 0000000..f272eac Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-mobile.png new file mode 100644 index 0000000..8424716 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-webkit.png new file mode 100644 index 0000000..63e2e67 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-card-normal-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-chromium.png new file mode 100644 index 0000000..e0355c8 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-firefox.png new file mode 100644 index 0000000..124fcc2 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-mobile.png new file mode 100644 index 0000000..4950f4c Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-webkit.png new file mode 100644 index 0000000..c3ab0bb Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/feature-grid-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/footer-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/footer-chromium.png new file mode 100644 index 0000000..faed74c Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/footer-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/footer-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/footer-firefox.png new file mode 100644 index 0000000..6446a96 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/footer-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/footer-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/footer-mobile.png new file mode 100644 index 0000000..15923af Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/footer-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/footer-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/footer-webkit.png new file mode 100644 index 0000000..9d5ea38 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/footer-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/header-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/header-chromium.png new file mode 100644 index 0000000..db30faf Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/header-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/header-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/header-firefox.png new file mode 100644 index 0000000..86d0218 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/header-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/header-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/header-mobile.png new file mode 100644 index 0000000..5446ffe Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/header-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/header-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/header-webkit.png new file mode 100644 index 0000000..404f960 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/header-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-chromium.png new file mode 100644 index 0000000..23de29e Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-chromium.png new file mode 100644 index 0000000..82204c4 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-firefox.png new file mode 100644 index 0000000..93cd234 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-mobile.png new file mode 100644 index 0000000..d4c949a Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-webkit.png new file mode 100644 index 0000000..2fa248a Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-desktop-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-firefox.png new file mode 100644 index 0000000..0c6a245 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-chromium.png new file mode 100644 index 0000000..3d5839f Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-firefox.png new file mode 100644 index 0000000..99b18ca Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-mobile.png new file mode 100644 index 0000000..4e121f9 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-webkit.png new file mode 100644 index 0000000..53a27ca Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile.png new file mode 100644 index 0000000..cc5c087 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-chromium.png new file mode 100644 index 0000000..f5e5dfa Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-firefox.png new file mode 100644 index 0000000..2e711f0 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-mobile.png new file mode 100644 index 0000000..7c9664a Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-webkit.png new file mode 100644 index 0000000..9531f86 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-tablet-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-webkit.png new file mode 100644 index 0000000..8a4580d Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/hero-banner-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-chromium.png new file mode 100644 index 0000000..21e3a96 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-firefox.png new file mode 100644 index 0000000..ad87b3c Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-mobile.png new file mode 100644 index 0000000..8ddc0c1 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-webkit.png new file mode 100644 index 0000000..ce23804 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-dark-mode-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-chromium.png new file mode 100644 index 0000000..a9a4ef8 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-firefox.png new file mode 100644 index 0000000..589b89f Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-mobile.png new file mode 100644 index 0000000..09936f2 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-webkit.png new file mode 100644 index 0000000..5a5a695 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-desktop-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-chromium.png new file mode 100644 index 0000000..061b8b9 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-firefox.png new file mode 100644 index 0000000..f55087e Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-mobile.png new file mode 100644 index 0000000..8ddc0c1 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-webkit.png new file mode 100644 index 0000000..ce23804 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-error-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-chromium.png new file mode 100644 index 0000000..15ed28f Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-firefox.png new file mode 100644 index 0000000..eb54aed Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-mobile.png new file mode 100644 index 0000000..c5e1564 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-webkit.png new file mode 100644 index 0000000..ee7a41e Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-full-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-chromium.png new file mode 100644 index 0000000..074145c Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-firefox.png new file mode 100644 index 0000000..4bae5e5 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-mobile.png new file mode 100644 index 0000000..e4b0fc2 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-webkit.png new file mode 100644 index 0000000..2f64f98 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-high-contrast-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-chromium.png new file mode 100644 index 0000000..6dd8cba Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-firefox.png new file mode 100644 index 0000000..9e4e9fd Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-mobile.png new file mode 100644 index 0000000..2deedf0 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-webkit.png new file mode 100644 index 0000000..f896758 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-large-desktop-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-chromium.png new file mode 100644 index 0000000..f0c7436 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-firefox.png new file mode 100644 index 0000000..38fe3c8 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-mobile.png new file mode 100644 index 0000000..ebb452d Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-webkit.png new file mode 100644 index 0000000..ce23804 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-loading-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-chromium.png new file mode 100644 index 0000000..43600ee Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-firefox.png new file mode 100644 index 0000000..aa27dd8 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-mobile.png new file mode 100644 index 0000000..45f671e Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-webkit.png new file mode 100644 index 0000000..236048e Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-mobile-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-chromium.png new file mode 100644 index 0000000..21e3a96 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-firefox.png new file mode 100644 index 0000000..38fe3c8 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-mobile.png new file mode 100644 index 0000000..8ddc0c1 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-webkit.png new file mode 100644 index 0000000..ce23804 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-reduced-motion-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-chromium.png new file mode 100644 index 0000000..e6a7bf6 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-firefox.png new file mode 100644 index 0000000..6c299b4 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-mobile.png new file mode 100644 index 0000000..4466c8c Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-webkit.png new file mode 100644 index 0000000..8e33e06 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-tablet-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-chromium.png new file mode 100644 index 0000000..21e3a96 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-firefox.png new file mode 100644 index 0000000..38fe3c8 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-mobile.png new file mode 100644 index 0000000..8ddc0c1 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-webkit.png new file mode 100644 index 0000000..f3b8ee0 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/homepage-viewport-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-chromium.png new file mode 100644 index 0000000..e1290ea Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-firefox.png new file mode 100644 index 0000000..a054565 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-mobile.png new file mode 100644 index 0000000..2cea43b Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-webkit.png new file mode 100644 index 0000000..42f5a6a Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-hover-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-chromium.png new file mode 100644 index 0000000..f16f07c Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-firefox.png new file mode 100644 index 0000000..d3dde81 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-mobile.png new file mode 100644 index 0000000..2cea43b Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-webkit.png new file mode 100644 index 0000000..9a48360 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-normal-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-chromium.png new file mode 100644 index 0000000..ac8849c Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-firefox.png new file mode 100644 index 0000000..21c023b Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-mobile.png new file mode 100644 index 0000000..7f8cfc9 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-webkit.png new file mode 100644 index 0000000..39e1612 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/logo-wall-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-chromium.png new file mode 100644 index 0000000..8d25ade Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-firefox.png new file mode 100644 index 0000000..2bcac80 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-mobile.png new file mode 100644 index 0000000..3df5443 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-webkit.png new file mode 100644 index 0000000..6f7b059 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/numbered-cards-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-chromium.png new file mode 100644 index 0000000..5cdf241 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-firefox.png new file mode 100644 index 0000000..9647184 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-mobile.png new file mode 100644 index 0000000..02fe1b6 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-webkit.png new file mode 100644 index 0000000..8a949b7 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/quote-block-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-chromium.png new file mode 100644 index 0000000..4f930ca Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-firefox.png new file mode 100644 index 0000000..54adeae Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-mobile.png new file mode 100644 index 0000000..3dbc46e Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-webkit.png new file mode 100644 index 0000000..d37aa09 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-hover-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-chromium.png new file mode 100644 index 0000000..3fa8b2e Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-firefox.png new file mode 100644 index 0000000..a3bcd3d Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-mobile.png new file mode 100644 index 0000000..3dbc46e Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-webkit.png new file mode 100644 index 0000000..1d128d6 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-card-normal-webkit.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-chromium.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-chromium.png new file mode 100644 index 0000000..0013958 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-chromium.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-firefox.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-firefox.png new file mode 100644 index 0000000..d966d8c Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-firefox.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-mobile.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-mobile.png new file mode 100644 index 0000000..5e00201 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-mobile.png differ diff --git a/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-webkit.png b/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-webkit.png new file mode 100644 index 0000000..4e03769 Binary files /dev/null and b/tests/e2e/visual-regression.spec.ts-snapshots/rule-stack-webkit.png differ diff --git a/tests/integration/ContentLockup.integration.test.jsx b/tests/integration/ContentLockup.integration.test.jsx new file mode 100644 index 0000000..1bdaec7 --- /dev/null +++ b/tests/integration/ContentLockup.integration.test.jsx @@ -0,0 +1,156 @@ +import { render, screen, cleanup } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { vi, describe, test, expect, afterEach } from "vitest"; +import ContentLockup from "../../app/components/ContentLockup"; + +afterEach(() => { + cleanup(); +}); + +describe("ContentLockup Integration", () => { + test("renders hero variant with all content", () => { + render( + + ); + + expect( + screen.getByRole("heading", { name: "Welcome" }) + ).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: "Get Started" }) + ).toBeInTheDocument(); + expect(screen.getByText("This is a description")).toBeInTheDocument(); + expect(screen.getAllByRole("button", { name: "Get Started" })).toHaveLength( + 3 + ); + }); + + test("renders feature variant with link", () => { + render( + + ); + + expect( + screen.getByRole("heading", { name: "Feature Title" }) + ).toBeInTheDocument(); + expect( + screen.getByRole("link", { name: "Learn More" }) + ).toBeInTheDocument(); + expect(screen.getByRole("link", { name: "Learn More" })).toHaveAttribute( + "href", + "/learn" + ); + }); + + test("renders ask variant with simplified structure", () => { + render( + + ); + + expect( + screen.getByRole("heading", { name: "Ask Question" }) + ).toBeInTheDocument(); + expect( + screen.getByRole("heading", { name: "Ask subtitle" }) + ).toBeInTheDocument(); + // Ask variant should not have description or CTA + expect(screen.queryByRole("button")).not.toBeInTheDocument(); + }); + + test("handles left alignment", () => { + render( + + ); + + const container = screen + .getByRole("heading", { name: "Left Aligned" }) + .closest("div"); + expect(container).toHaveClass("justify-start"); + }); + + test("renders responsive buttons correctly", () => { + render( + + ); + + // Should render all three button variants for different breakpoints + const buttons = screen.getAllByRole("button", { name: "Click Me" }); + expect(buttons).toHaveLength(3); + }); + + test("applies custom button className", () => { + render( + + ); + + const buttons = screen.getAllByRole("button", { name: "Custom" }); + // The large button (md breakpoint) should have the custom class + expect(buttons[1]).toHaveClass("custom-button-class"); + }); + + test("handles missing optional props gracefully", () => { + render(); + + expect( + screen.getByRole("heading", { name: "Minimal" }) + ).toBeInTheDocument(); + // Should not crash without subtitle, description, or CTA + expect(screen.queryByRole("button")).not.toBeInTheDocument(); + }); + + test("renders decorative shape for hero variant", () => { + render(); + + const shape = screen.getByAltText("Decorative shapes"); + expect(shape).toBeInTheDocument(); + expect(shape).toHaveAttribute("src", "assets/Shapes_1.svg"); + }); + + test("does not render shape for non-hero variants", () => { + render(); + + expect(screen.queryByAltText("Decorative shapes")).not.toBeInTheDocument(); + }); + + test("link has proper accessibility attributes", () => { + render( + + ); + + const link = screen.getByRole("link", { name: "Accessible Link" }); + expect(link).toHaveAttribute("href", "/accessible"); + expect(link).toHaveClass("focus:outline-none", "focus:ring-2"); + }); +}); diff --git a/tests/integration/component-interactions.integration.test.jsx b/tests/integration/component-interactions.integration.test.jsx new file mode 100644 index 0000000..636b899 --- /dev/null +++ b/tests/integration/component-interactions.integration.test.jsx @@ -0,0 +1,353 @@ +import { render, screen, cleanup } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { vi, describe, test, expect, afterEach } from "vitest"; +import HeroBanner from "../../app/components/HeroBanner"; +import NumberedCards from "../../app/components/NumberedCards"; +import RuleStack from "../../app/components/RuleStack"; +import FeatureGrid from "../../app/components/FeatureGrid"; +import QuoteBlock from "../../app/components/QuoteBlock"; +import AskOrganizer from "../../app/components/AskOrganizer"; + +afterEach(() => { + cleanup(); +}); + +describe("Component Interactions Integration", () => { + test("hero banner and numbered cards work together to explain the process", () => { + const heroData = { + title: "Collaborate", + subtitle: "with clarity", + description: + "Help your community make important decisions in a way that reflects its unique values.", + ctaText: "Learn how CommunityRule works", + ctaHref: "#", + }; + + const numberedCardsData = { + title: "How CommunityRule works", + subtitle: "Here's a quick overview of the process, from start to finish.", + cards: [ + { + text: "Document how your community makes decisions", + iconShape: "blob", + iconColor: "green", + }, + { + text: "Build an operating manual for a successful community", + iconShape: "gear", + iconColor: "purple", + }, + { + text: "Get a link to your manual for your group to review and evolve", + iconShape: "star", + iconColor: "orange", + }, + ], + }; + + render( +
+ + +
+ ); + + // Hero introduces the concept + expect( + screen.getByText(/Help your community make important decisions/) + ).toBeInTheDocument(); + + // Numbered cards explain the process + expect(screen.getByText("How CommunityRule works")).toBeInTheDocument(); + expect( + screen.getByText("Document how your community makes decisions") + ).toBeInTheDocument(); + expect( + screen.getByText("Build an operating manual for a successful community") + ).toBeInTheDocument(); + expect( + screen.getByText( + "Get a link to your manual for your group to review and evolve" + ) + ).toBeInTheDocument(); + }); + + test("rule stack and feature grid complement each other", () => { + const featureGridData = { + title: "We've got your back, every step of the way", + subtitle: + "Use our toolkit to improve, document, and evolve your organization.", + }; + + render( +
+ + +
+ ); + + // Rule stack shows governance options + expect(screen.getByText("Consensus clusters")).toBeInTheDocument(); + expect(screen.getByText("Elected Board")).toBeInTheDocument(); + expect(screen.getByText("Consensus")).toBeInTheDocument(); + expect(screen.getByText("Petition")).toBeInTheDocument(); + + // Feature grid provides support context + expect( + screen.getByText("We've got your back, every step of the way") + ).toBeInTheDocument(); + expect( + screen.getByText( + "Use our toolkit to improve, document, and evolve your organization." + ) + ).toBeInTheDocument(); + }); + + test("quote block provides social proof for the entire application", () => { + render(); + + // Quote provides credibility and social proof + expect( + screen.getByText(/The rules of decision-making must be open/) + ).toBeInTheDocument(); + + // Should have proper attribution + expect(screen.getByText("Jo Freeman")).toBeInTheDocument(); + expect( + screen.getByText("The Tyranny of Structurelessness") + ).toBeInTheDocument(); + }); + + test("ask organizer provides help context for all components", () => { + const askOrganizerData = { + title: "Still have questions?", + subtitle: "Get answers from an experienced organizer", + buttonText: "Ask an organizer", + buttonHref: "#contact", + }; + + render(); + + // Provides help for users who need assistance + expect(screen.getByText("Still have questions?")).toBeInTheDocument(); + expect( + screen.getByText("Get answers from an experienced organizer") + ).toBeInTheDocument(); + expect( + screen.getByRole("link", { name: /Ask an organizer/i }) + ).toBeInTheDocument(); + }); + + test("all components maintain consistent styling and branding", () => { + render( +
+ + + + + + +
+ ); + + // All components should render without errors + expect(screen.getAllByText("Test").length).toBeGreaterThan(0); + expect(screen.getByText("Test Cards")).toBeInTheDocument(); + expect(screen.getByText("Consensus clusters")).toBeInTheDocument(); + expect(screen.getByText("Test Features")).toBeInTheDocument(); + expect( + screen.getByText(/The rules of decision-making must be open/) + ).toBeInTheDocument(); + expect(screen.getByText("Test Help")).toBeInTheDocument(); + }); + + test("components handle data flow and prop passing correctly", () => { + const testData = { + hero: { + title: "Test Hero", + subtitle: "Test Subtitle", + description: "Test description", + ctaText: "Test CTA", + ctaHref: "/test", + }, + cards: { + title: "Test Cards", + subtitle: "Test subtitle", + cards: [ + { text: "Card 1", iconShape: "blob", iconColor: "green" }, + { text: "Card 2", iconShape: "gear", iconColor: "purple" }, + ], + }, + features: { + title: "Test Features", + subtitle: "Test features subtitle", + }, + help: { + title: "Test Help", + subtitle: "Test help subtitle", + buttonText: "Test Help Button", + buttonHref: "/help", + }, + }; + + render( +
+ + + + +
+ ); + + // Verify all data is passed correctly + expect(screen.getByText("Test Hero")).toBeInTheDocument(); + expect(screen.getByText("Test Subtitle")).toBeInTheDocument(); + expect(screen.getByText("Test description")).toBeInTheDocument(); + expect( + screen.getAllByRole("button", { name: "Test CTA" }).length + ).toBeGreaterThan(0); + expect(screen.getByText("Test Cards")).toBeInTheDocument(); + expect(screen.getByText("Card 1")).toBeInTheDocument(); + expect(screen.getByText("Card 2")).toBeInTheDocument(); + expect(screen.getByText("Test Features")).toBeInTheDocument(); + expect(screen.getByText("Test Help")).toBeInTheDocument(); + expect( + screen.getByRole("link", { name: /Test Help Button/i }) + ).toBeInTheDocument(); + }); + + test("components work together to create a cohesive user experience", async () => { + const user = userEvent.setup(); + + render( +
+ + + + + + +
+ ); + + // Test interaction flow + const learnButtons = screen.getAllByRole("button", { name: "Learn more" }); + await user.click(learnButtons[0]); + + const createButtons = screen.getAllByRole("button", { + name: "Create CommunityRule", + }); + if (createButtons.length > 0) { + await user.click(createButtons[0]); + } + + const contactButton = screen.getByRole("link", { name: /Contact us/i }); + await user.click(contactButton); + + // All components should remain functional + expect(screen.getByText("Collaborate")).toBeInTheDocument(); + expect(screen.getByText("How it works")).toBeInTheDocument(); + expect(screen.getByText("Consensus clusters")).toBeInTheDocument(); + expect(screen.getByText("Features")).toBeInTheDocument(); + expect( + screen.getByText(/The rules of decision-making must be open/) + ).toBeInTheDocument(); + expect(screen.getByText("Need help?")).toBeInTheDocument(); + }); + + test("components handle edge cases and missing data gracefully", () => { + // Test with minimal data + render( +
+ + + + +
+ ); + + // Components should render without crashing + expect(screen.getByText("Minimal Hero")).toBeInTheDocument(); + expect(screen.getByText("Minimal Cards")).toBeInTheDocument(); + expect(screen.getByText("Minimal Features")).toBeInTheDocument(); + expect(screen.getByText("Minimal Help")).toBeInTheDocument(); + }); + + test("components maintain accessibility when used together", () => { + render( +
+ + + + + + +
+ ); + + // Check for proper heading hierarchy + const headings = screen.getAllByRole("heading"); + expect(headings.length).toBeGreaterThan(0); + + // Check for proper button roles + const buttons = screen.getAllByRole("button"); + buttons.forEach((button) => { + expect(button).toBeInTheDocument(); + }); + + // Check for proper link roles + const links = screen.getAllByRole("link"); + links.forEach((link) => { + expect(link).toBeInTheDocument(); + }); + }); +}); diff --git a/tests/integration/layout.integration.test.jsx b/tests/integration/layout.integration.test.jsx new file mode 100644 index 0000000..7daac5d --- /dev/null +++ b/tests/integration/layout.integration.test.jsx @@ -0,0 +1,240 @@ +import { render, screen, cleanup } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { vi, describe, test, expect, afterEach } from "vitest"; +import Header from "../../app/components/Header"; +import Footer from "../../app/components/Footer"; + +afterEach(() => { + cleanup(); +}); + +describe("Layout Integration", () => { + test("header and footer provide consistent branding", () => { + render( +
+
+
+
+ ); + + // Check that CommunityRule branding appears in both header and footer + const headerLogos = screen.getAllByAltText("CommunityRule Logo Icon"); + expect(headerLogos.length).toBeGreaterThan(0); + + // Footer should have the organization name + expect(screen.getByText("Media Economies Design Lab")).toBeInTheDocument(); + }); + + test("navigation is consistent between header and footer", () => { + render( +
+
+
+
+ ); + + // Header navigation items + expect( + screen.getAllByRole("menuitem", { name: "Navigate to Use cases page" }) + .length + ).toBeGreaterThan(0); + expect( + screen.getAllByRole("menuitem", { name: "Navigate to Learn page" }).length + ).toBeGreaterThan(0); + expect( + screen.getAllByRole("menuitem", { name: "Navigate to About page" }).length + ).toBeGreaterThan(0); + + // Footer navigation items (should be present in footer as well) + const useCasesLinks = screen.getAllByRole("link", { name: "Use cases" }); + const learnLinks = screen.getAllByRole("link", { name: "Learn" }); + const aboutLinks = screen.getAllByRole("link", { name: "About" }); + + expect(useCasesLinks.length).toBeGreaterThan(0); + expect(learnLinks.length).toBeGreaterThan(0); + expect(aboutLinks.length).toBeGreaterThan(0); + }); + + test("header navigation is interactive", async () => { + const user = userEvent.setup(); + render(
); + + // Test navigation links + const useCasesLinks = screen.getAllByRole("menuitem", { + name: "Navigate to Use cases page", + }); + const learnLinks = screen.getAllByRole("menuitem", { + name: "Navigate to Learn page", + }); + const aboutLinks = screen.getAllByRole("menuitem", { + name: "Navigate to About page", + }); + + const useCasesLink = useCasesLinks[0]; + const learnLink = learnLinks[0]; + const aboutLink = aboutLinks[0]; + + expect(useCasesLink).toHaveAttribute("href", "#"); + expect(learnLink).toHaveAttribute("href", "#"); + expect(aboutLink).toHaveAttribute("href", "#"); + + // Test button interactions + const createRuleButtons = screen.getAllByRole("button", { + name: "Create a new rule with avatar decoration", + }); + await user.click(createRuleButtons[0]); + expect(createRuleButtons[0]).toBeInTheDocument(); + }); + + test("footer provides contact and social information", () => { + render(