# Technical Documentation: lewish/asciiflow

> ℹ️ **Provenance:** In-Tree Documentation (9 Chapters) · [CodeWiki Reference](https://codewiki.google/github.com/lewish/asciiflow) · Recency: Active (< 180 days)

## File: README.md

# [asciiflow.com](https://asciiflow.com)

ASCIIFlow is a client-side only web based application for drawing ASCII diagrams. You can use it at [asciiflow.com](https://asciiflow.com).



## Contributing

### Installation

ASCIIFlow is built with [Bazel](https://docs.bazel.build/versions/4.0.0/getting-started.html).
Bazel is most easily installed to the correct version through [Bazelisk](https://github.com/bazelbuild/bazelisk). See `.bazelversion` for the correct version if you aren't using Bazelisk.

```
npm install -g @bazel/bazelisk
yarn global add @bazel/bazelisk
```

For development, ibazel is also a very useful tool to help with automatic rebuilding and reloading.

```
npm install -g @bazel/ibazel
yarn global add @bazel/ibazel
```

### Running ASCIIFlow locally

After installation of Bazel/Bazelisk, you can run ASCIIFlow locally with:

```
ibazel run client:devserver
```

Or without ibazel (won't do live reloading):

```
bazel run client:devserver
```

---

## File: CLAUDE.md

# ASCIIFlow

ASCII diagram drawing web app (asciiflow.com). Client-side only, also runs as Electron desktop app.

## Stack

- **Language:** TypeScript 5.8
- **UI:** React 16.14.0 + Material-UI 4.12.4
- **Routing:** React Router DOM 5.3.4
- **Build:** Bazel 8 (via Bazelisk) + esbuild (via aspect_rules_esbuild)
- **Tests:** Mocha + Chai + Sinon (unit), Playwright (e2e)
- **Desktop:** Electron 29.0.1

## Build & Dev

```bash
bazel build client:bundle      # Production build (esbuild)
bazel build client:site         # Full site with static assets
bazel test //common:all         # Common tests only
bazel test //client:all         # Client tests only
bazel test //e2e:all            # Playwright e2e tests
```

Requires Node 22.x (managed by Bazel toolchain) and Bazel 8.x (via Bazelisk).

## Project Structure

```
client/                # Main frontend app
  store/               # State management (Zustand)
    index.ts           # Store singleton, ToolMode enum, tool instances
    canvas.ts          # Per-drawing state (layers, undo/redo, zoom)
    drawing_stringifier.ts  # Compress/share drawings via URL
  draw/                # Drawing tool implementations (IDrawFunction interface)
    box.ts, line.ts, text.ts, select.ts, freeform.ts, erase.ts, move.ts
  components/          # Reusable React components
  app.tsx              # React entry point with router
  controller.ts        # Input event handling (desktop + touch)
  view.tsx             # Canvas rendering (HTML5 canvas)
  layer.ts             # Sparse grid data model (Vector → char)
  vector.ts            # 2D vector math
  constants.ts         # Character sets, grid dimensions, input config
  drawer.tsx           # Sidebar UI (tools, file management, export)
  export.tsx           # Export (SVG, HTML, PNG, Markdown, JSON)
common/                # Shared utilities
  stringifiers.ts      # Serialization interfaces
testing/               # Test infrastructure
  test_setup.ts        # localStorage/window shim for Node.js tests
bazel/                 # Bazel build infrastructure
  playwright.bzl       # playwright_test() rule for e2e tests
  playwright-runner.mjs # Playwright test runner with static server
  resolve-extensions-loader.mjs # ESM loader for .ts extension resolution
e2e/                   # Playwright e2e tests
  app.spec.js          # Application e2e tests
  playwright.config.mjs # Playwright configuration
electron/              # Electron desktop wrapper
site/                  # Static site assets
```

## Architecture

- **State:** Zustand store (`client/store/index.ts`). `Store` is a singleton. React components subscribe via Zustand's `useStore()` hook with selectors.
- **Drawing:** Command pattern — Controller dispatches input to the active `IDrawFunction` tool. Tools write to a scratch `Layer`, which is applied on commit.
- **Layers:** Sparse grid (`Map<string, string>` keyed by Vector). `LayerView` composes multiple layers for rendering.
- **Persistence:** Direct `localStorage.getItem`/`setItem` with `IStringifier` serialization (in store/index.ts and store/canvas.ts).
- **Sharing:** Drawing → JSON → pako deflate → base64 → URL param at `/share/:encoded`.
- **Routes:** `/` (new), `/local/:id` (saved), `/share/:encoded` (shared read-only).

## Conventions

- TypeScript with strict type checking
- React functional components with hooks
- Bazel BUILD files per directory
- Unit tests use `.spec.ts` suffix alongside source files
- E2e tests use `.spec.js` in `e2e/` directory
- Path alias: `#asciiflow/*` maps to repo root
- CSS modules for component styling
- Drawing tools implement `IDrawFunction` with: `start()`, `move()`, `end()`, `handleKey()`, `getCursor()`

## Issue Priority List

Re-triaged July 13, 2026 after the v1.1.0 production release and the merge of PR #368. See GitHub issues for full details.

### Recently shipped and closed in v1.1.0

These were previously labelled `fixed-in-staging`. The fixes are in tag `v1.1.0`, are live on asciiflow.com, and the issues have been closed or had the stale label removed.

| Issue | Summary |
|-------|---------|
| #28 | Pan/zoom UX, scroll pans and Cmd/Ctrl+scroll zooms |
| #129 | Two-finger swipe panning |
| #187 | Line breaks in paste and export normalization |
| #189 | Ctrl/Cmd+Z browser undo prevention |
| #193 | Backspace in text mode moves and clears correctly |
| #195 | Space-to-pan in text mode conflict |
| #246 | Visible gridlines toggle in view panel |
| #258 | Blurry canvas on HiDPI/Retina displays |
| #297 | Space and Delete in text mode |
| #307 | Delete works for the first scene |
| #321 | Side-scroll wheel behaviour |
| #332 | Undo while typing no longer reverts previous drawing action |
| #338 | Copy/paste on macOS Safari/Firefox via native clipboard events |

### Merged to main, pending next production release

| Issue / PR | Summary |
|------------|---------|
| #368 | Entity-aware select/move tool and smarter snapping. Boxes move from their interior, attached lines reflow, line tips reshape, words move, rubber-band selections keep connected lines tidier. |
| #58 | Partially addressed by #368, but still open because a full object model for arbitrary element manipulation is broader than the current select-tool work. |

### Open bugs

| Issue | Summary |
|-------|---------|
| #202 | Firefox Quick Find still reported for apostrophe/slash after the original v1.1.0 fix, needs fresh repro on current production |
| #211 | Spaces broken during export |
| #85 | CJK character support, fullwidth characters and IME input |

### Feature Requests, High Priority

| Issue | Summary |
|-------|---------|
| #241 | Customisable line/border/corner styles, including Unicode variants, rounded corners, ASCII mode, dashed lines |
| #361 | Different characters for boxes and lines, likely folds into #241 |
| #43 | Diagonal lines |
| #54 | Export selected area only |
| #346 | PWA support for offline/installable use, likely replaces Electron |

### Feature Requests, Moderate Priority

| Issue | Summary |
|-------|---------|
| #162 | Vertical/horizontal flip and 90-degree rotation |
| #76 | Auto-centre text within boxes |
| #324 | Remember cursor position across select/text tool switches |
| #240 | Text tool insert mode in addition to overwrite |
| #303 | Ctrl+arrow for word navigation in text mode |
| #337 | Distinguishing crossing arrows, for example ╫ or similar |
| #259 | Table generator with specified rows/columns |
| #200 | Drag/move with arrow keys |
| #197 | Set exact size for lines/boxes |

### Feature Requests, Lower Priority / Longer Term

| Issue | Summary |
|-------|---------|
| #44 | Configurable or limited drawing area |
| #229 | Circle/ellipse support |
| #134 | Trapezoid/mux shapes |
| #336 | Colour support |
| #273 | Pixel-perfect freeform lines |
| #219 | Copy/paste characters in freeform mode |

### Non-action / community

| Issue | Summary |
|-------|---------|
| #369 | Thank-you issue. Needs a friendly reply and can probably be closed afterwards. |

---

## File: package.json

{
  "name": "asciiflow2",
  "main": "index.js",
  "icon": "images/favicon.png",
  "imports": {
    "#asciiflow/*": "./*"
  },
  "scripts": {
    "start": "electron ."
  },
  "type": "module",
  "dependencies": {
    "@playwright/test": "^1.49.0",
    "playwright": "^1.49.0",
    "playwright-core": "^1.49.0",
    "@types/chai": "^4.3.12",
    "@types/diff": "^5.0.9",
    "@types/json-stable-stringify": "^1.0.36",
    "@types/mocha": "^10.0.6",
    "@types/node": "^22.0.0",
    "@types/pako": "^1.0.7",
    "@types/react": "^16.14.56",
    "@types/react-dom": "^16.9.24",
    "@types/react-router": "^5.1.20",
    "@types/react-router-dom": "^5.3.3",
    "@types/sinon": "^17.0.3",
    "@types/uuid": "^8.3.4",
    "chai": "^4.4.1",
    "electron": "^29.0.1",
    "http-server": "^14.1.1",
    "js-base64": "^3.7.7",
    "json-stable-stringify": "^1.1.1",
    "mocha": "^11.0.0",
    "pako": "^1.0.11",
    "react": "^16.14.0",
    "react-dom": "^16.14.0",
    "react-router": "^5.3.4",
    "react-router-dom": "^5.3.4",
    "sinon": "^18.0.0",
    "source-map-support": "^0.5.21",
    "typescript": "^5.7.0",
    "uuid": "^8.3.2",
    "zustand": "^4.5.5"
  },
  "pnpm": {
    "overrides": {
      "postcss@<7.0.36": ">=7.0.36",
      "postcss@<8.4.31": ">=8.4.31",
      "minimist@<0.2.1": ">=0.2.1",
      "minimatch@<3.0.5": ">=3.0.5",
      "minimist@<0.2.4": ">=0.2.4"
    }
  }
}

---

## File: pnpm-lock.yaml

lockfileVersion: '6.0'

settings:
  autoInstallPeers: true
  excludeLinksFromLockfile: false

overrides:
  postcss@<7.0.36: '>=7.0.36'
  postcss@<8.4.31: '>=8.4.31'
  minimist@<0.2.1: '>=0.2.1'
  minimatch@<3.0.5: '>=3.0.5'
  minimist@<0.2.4: '>=0.2.4'

dependencies:
  '@playwright/test':
    specifier: ^1.49.0
    version: 1.58.2
  '@types/chai':
    specifier: ^4.3.12
    version: 4.3.12
  '@types/diff':
    specifier: ^5.0.9
    version: 5.0.9
  '@types/json-stable-stringify':
    specifier: ^1.0.36
    version: 1.0.36
  '@types/mocha':
    specifier: ^10.0.6
    version: 10.0.6
  '@types/node':
    specifier: ^22.0.0
    version: 22.19.11
  '@types/pako':
    specifier: ^1.0.7
    version: 1.0.7
  '@types/react':
    specifier: ^16.14.56
    version: 16.14.56
  '@types/react-dom':
    specifier: ^16.9.24
    version: 16.9.24
  '@types/react-router':
    specifier: ^5.1.20
    version: 5.1.20
  '@types/react-router-dom':
    specifier: ^5.3.3
    version: 5.3.3
  '@types/sinon':
    specifier: ^17.0.3
    version: 17.0.3
  '@types/uuid':
    specifier: ^8.3.4
    version: 8.3.4
  chai:
    specifier: ^4.4.1
    version: 4.4.1
  electron:
    specifier: ^29.0.1
    version: 29.0.1
  http-server:
    specifier: ^14.1.1
    version: 14.1.1
  js-base64:
    specifier: ^3.7.7
    version: 3.7.7
  json-stable-stringify:
    specifier: ^1.1.1
    version: 1.1.1
  mocha:
    specifier: ^11.0.0
    version: 11.7.5
  pako:
    specifier: ^1.0.11
    version: 1.0.11
  playwright:
    specifier: ^1.49.0
    version: 1.58.2
  playwright-core:
    specifier: ^1.49.0
    version: 1.58.2
  react:
    specifier: ^16.14.0
    version: 16.14.0
  react-dom:
    specifier: ^16.14.0
    version: 16.14.0(react@16.14.0)
  react-router:
    specifier: ^5.3.4
    version: 5.3.4(react@16.14.0)
  react-router-dom:
    specifier: ^5.3.4
    version: 5.3.4(react@16.14.0)
  sinon:
    specifier: ^18.0.0
    version: 18.0.0
  source-map-support:
    specifier: ^0.5.21
    version: 0.5.21
  typescript:
    specifier: ^5.7.0
    version: 5.9.3
  uuid:
    specifier: ^8.3.2
    version: 8.3.2
  zustand:
    specifier: ^4.5.5
    version: 4.5.7(@types/react@16.14.56)(react@16.14.0)

packages:

  /@babel/runtime@7.23.9:
    resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==}
    engines: {node: '>=6.9.0'}
    dependencies:
      regenerator-runtime: 0.14.1
    dev: false

  /@electron/get@2.0.3:
    resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==}
    engines: {node: '>=12'}
    dependencies:
      debug: 4.3.4
      env-paths: 2.2.1
      fs-extra: 8.1.0
      got: 11.8.6
      progress: 2.0.3
      semver: 6.3.1
      sumchecker: 3.0.1
    optionalDependencies:
      global-agent: 3.0.0
    transitivePeerDependencies:
      - supports-color
    dev: false

  /@isaacs/cliui@8.0.2:
    resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
    engines: {node: '>=12'}
    dependencies:
      string-width: 5.1.2
      string-width-cjs: /string-width@4.2.3
      strip-ansi: 7.1.2
      strip-ansi-cjs: /strip-ansi@6.0.1
      wrap-ansi: 8.1.0
      wrap-ansi-cjs: /wrap-ansi@7.0.0
    dev: false

  /@pkgjs/parseargs@0.11.0:
    resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
    engines: {node: '>=14'}
    requiresBuild: true
    dev: false
    optional: true

  /@playwright/test@1.58.2:
    resolution: {integrity: sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==}
    engines: {node: '>=18'}
    hasBin: true
    dependencies:
      playwright: 1.58.2
    dev: false

  /@sindresorhus/is@4.6.0:
    resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
    engines: {node: '>=10'}
    dev: false

  /@sinonjs/commons@2.0.0:
    resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==}
    dependencies:
      type-detect: 4.0.8
    dev: false

  /@sinonjs/commons@3.0.1:
    resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==}
    dependencies:
      type-detect: 4.0.8
    dev: false

  /@sinonjs/fake-timers@11.2.2:
    resolution: {integrity: sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==}
    dependencies:
      '@sinonjs/commons': 3.0.1
    dev: false

  /@sinonjs/samsam@8.0.0:
    resolution: {integrity: sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==}
    dependencies:
      '@sinonjs/commons': 2.0.0
      lodash.get: 4.4.2
      type-detect: 4.0.8
    dev: false

  /@sinonjs/text-encoding@0.7.2:
    resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==}
    dev: false

  /@szmarczak/http-timer@4.0.6:
    resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==}
    engines: {node: '>=10'}
    dependencies:
      defer-to-connect: 2.0.1
    dev: false

  /@types/cacheable-request@6.0.3:
    resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==}
    dependencies:
      '@types/http-cache-semantics': 4.0.4
      '@types/keyv': 3.1.4
      '@types/node': 22.19.11
      '@types/responselike': 1.0.3
    dev: false

  /@types/chai@4.3.12:
    resolution: {integrity: sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw==}
    dev: false

  /@types/diff@5.0.9:
    resolution: {integrity: sha512-RWVEhh/zGXpAVF/ZChwNnv7r4rvqzJ7lYNSmZSVTxjV0PBLf6Qu7RNg+SUtkpzxmiNkjCx0Xn2tPp7FIkshJwQ==}
    dev: false

  /@types/history@4.7.11:
    resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==}
    dev: false

  /@types/http-cache-semantics@4.0.4:
    resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==}
    dev: false

  /@types/json-stable-stringify@1.0.36:
    resolution: {integrity: sha512-b7bq23s4fgBB76n34m2b3RBf6M369B0Z9uRR8aHTMd8kZISRkmDEpPD8hhpYvDFzr3bJCPES96cm3Q6qRNDbQw==}
    dev: false

  /@types/keyv@3.1.4:
    resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
    dependencies:
      '@types/node': 22.19.11
    dev: false

  /@types/mocha@10.0.6:
    resolution: {integrity: sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==}
    dev: false

  /@types/node@20.11.20:
    resolution: {integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==}
    dependencies:
      undici-types: 5.26.5
    dev: false

  /@types/node@22.19.11:
    resolution: {integrity: sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==}
    dependencies:
      undici-types: 6.21.0
    dev: false

  /@types/pako@1.0.7:
    resolution: {integrity: sha512-YBtzT2ztNF6R/9+UXj2wTGFnC9NklAnASt3sC0h2m1bbH7G6FyBIkt4AN8ThZpNfxUo1b2iMVO0UawiJymEt8A==}
    dev: false

  /@types/prop-types@15.7.11:
    resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==}
    dev: false

  /@types/react-dom@16.9.24:
    resolution: {integrity: sha512-Gcmq2JTDheyWn/1eteqyzzWKSqDjYU6KYsIvH7thb7CR5OYInAWOX+7WnKf6PaU/cbdOc4szJItcDEJO7UGmfA==}
    dependencies:
      '@types/react': 16.14.56
    dev: false

  /@types/react-router-dom@5.3.3:
    resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==}
    dependencies:
      '@types/history': 4.7.11
      '@types/react': 16.14.56
      '@types/react-router': 5.1.20
    dev: false

  /@types/react-router@5.1.20:
    resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==}
    dependencies:
      '@types/history': 4.7.11
      '@types/react': 16.14.56
    dev: false

  /@types/react@16.14.56:
    resolution: {integrity: sha512-MxuHB7dvVm5yOxRr7hJoonLG0JY8YvqZtaQ9Quirp3Oe4FLFjAgxkxsKE6IspdHPpRVZKo2ZoDEravWO81EeYA==}
    dependencies:
      '@types/prop-types': 15.7.11
      '@types/scheduler': 0.16.8
      csstype: 3.1.3
    dev: false

  /@types/responselike@1.0.3:
    resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==}
    dependencies:
      '@types/node': 22.19.11
    dev: false

  /@types/scheduler@0.16.8:
    resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==}
    dev: false

  /@types/sinon@17.0.3:
    resolution: {integrity: sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==}
    dependencies:
      '@types/sinonjs__fake-timers': 8.1.5
    dev: false

  /@types/sinonjs__fake-timers@8.1.5:
    resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==}
    dev: false

  /@types/uuid@8.3.4:
    resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==}
    dev: false

  /@types/yauzl@2.10.3:
    resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
    requiresBuild: true
    dependencies:
      '@types/node': 22.19.11
    dev: false
    optional: true

  /ansi-regex@5.0.1:
    resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
    engines: {node: '>=8'}
    dev: false

  /ansi-regex@6.2.2:
    resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
    engines: {node: '>=12'}
    dev: false

  /ansi-styles@4.3.0:
    resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
    engines: {node: '>=8'}
    dependencies:
      color-convert: 2.0.1
    dev: false

  /ansi-styles@6.2.3:
    resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
    engines: {node: '>=12'}
    dev: false

  /argparse@2.0.1:
    resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
    dev: false

  /assertion-error@1.1.0:
    resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
    dev: false

  /async@3.2.6:
    resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
    dev: false

  /balanced-match@1.0.2:
    resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
    dev: false

  /basic-auth@2.0.1:
    resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==}
    engines: {node: '>= 0.8'}
    dependencies:
      safe-buffer: 5.1.2
    dev: false

  /boolean@3.2.0:
    resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==}
    requiresBuild: true
    dev: false
    optional: true

  /brace-expansion@2.0.1:
    resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
    dependencies:
      balanced-match: 1.0.2
    dev: false

  /browser-stdout@1.3.1:
    resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==}
    dev: false

  /buffer-crc32@0.2.13:
    resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
    dev: false

  /buffer-from@1.1.2:
    resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
    dev: false

  /cacheable-lookup@5.0.4:
    resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==}
    engines: {node: '>=10.6.0'}
    dev: false

  /cacheable-request@7.0.4:
    resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==}
    engines: {node: '>=8'}
    dependencies:
      clone-response: 1.0.3
      get-stream: 5.2.0
      http-cache-semantics: 4.1.1
      keyv: 4.5.4
      lowercase-keys: 2.0.0
      normalize-url: 6.1.0
      responselike: 2.0.1
    dev: false

  /call-bind@1.0.7:
    resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
    engines: {node: '>= 0.4'}
    dependencies:
      es-define-property: 1.0.0
      es-errors: 1.3.0
      function-bind: 1.1.2
      get-intrinsic: 1.2.4
      set-function-length: 1.2.1
    dev: false

  /camelcase@6.3.0:
    resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
    engines: {node: '>=10'}
    dev: false

  /chai@4.4.1:
    resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==}
    engines: {node: '>=4'}
    dependencies:
      assertion-error: 1.1.0
      check-error: 1.0.3
      deep-eql: 4.1.3
      get-func-name: 2.0.2
      loupe: 2.3.7
      pathval: 1.1.1
      type-detect: 4.0.8
    dev: false

  /chalk@4.1.2:
    resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
    engines: {node: '>=10'}
    dependencies:
      ansi-styles: 4.3.0
      supports-color: 7.2.0
    dev: false

  /check-error@1.0.3:
    resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==}
    dependencies:
      get-func-name: 2.0.2
    dev: false

  /chokidar@4.0.3:
    resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
    engines: {node: '>= 14.16.0'}
    dependencies:
      readdirp: 4.1.2
    dev: false

  /cliui@8.0.1:
    resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
    engines: {node: '>=12'}
    dependencies:
      string-width: 4.2.3
      strip-ansi: 6.0.1
      wrap-ansi: 7.0.0
    dev: false

  /clone-response@1.0.3:
    resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==}
    dependencies:
      mimic-response: 1.0.1
    dev: false

  /color-convert@2.0.1:
    resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
    engines: {node: '>=7.0.0'}
    dependencies:
      color-name: 1.1.4
    dev: false

  /color-name@1.1.4:
    resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
    dev: false

  /corser@2.0.1:
    resolution: {integrity: sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==}
    engines: {node: '>= 0.4.0'}
    dev: false

  /cross-spawn@7.0.6:
    resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
    engines: {node: '>= 8'}
    dependencies:
      path-key: 3.1.1
      shebang-command: 2.0.0
      which: 2.0.2
    dev: false

  /csstype@3.1.3:
    resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
    dev: false

  /debug@4.3.4:
    resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
    engines: {node: '>=6.0'}
    peerDependencies:
      supports-color: '*'
    peerDependenciesMeta:
      supports-color:
        optional: true
    dependencies:
      ms: 2.1.2
    dev: false

  /debug@4.4.3(supports-color@8.1.1):
    resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
    engines: {node: '>=6.0'}
    peerDependencies:
      supports-color: '*'
    peerDependenciesMeta:
      supports-color:
        optional: true
    dependencies:
      ms: 2.1.3
      supports-color: 8.1.1
    dev: false

  /decamelize@4.0.0:
    resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==}
    engines: {node: '>=10'}
    dev: false

  /decompress-response@6.0.0:
    resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
    engines: {node: '>=10'}
    dependencies:
      mimic-response: 3.1.0
    dev: false

  /deep-eql@4.1.3:
    resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
    engines: {node: '>=6'}
    dependencies:
      type-detect: 4.0.8
    dev: false

  /defer-to-connect@2.0.1:
    resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==}
    engines: {node: '>=10'}
    dev: false

  /define-data-property@1.1.4:
    resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
    engines: {node: '>= 0.4'}
    dependencies:
      es-define-property: 1.0.0
      es-errors: 1.3.0
      gopd: 1.0.1
    dev: false

  /define-properties@1.2.1:
    resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
    engines: {node: '>= 0.4'}
    requiresBuild: true
    dependencies:
      define-data-property: 1.1.4
      has-property-descriptors: 1.0.2
      object-keys: 1.1.1
    dev: false
    optional: true

  /detect-node@2.1.0:
    resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==}
    requiresBuild: true
    dev: false
    optional: true

  /diff@5.2.0:
    resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
    engines: {node: '>=0.3.1'}
    dev: false

  /diff@7.0.0:
    resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==}
    engines: {node: '>=0.3.1'}
    dev: false

  /eastasianwidth@0.2.0:
    resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
    dev: false

  /electron@29.0.1:
    resolution: {integrity: sha512-hsQr9clm8NCAMv4uhHlXThHn52UAgrHgyz3ubBAxZIPuUcpKVDtg4HPmx4hbmHIbYICI5OyLN3Ztp7rS+Dn4Lw==}
    engines: {node: '>= 12.20.55'}
    hasBin: true
    requiresBuild: true
    dependencies:
      '@electron/get': 2.0.3
      '@types/node': 20.11.20
      extract-zip: 2.0.1
    transitivePeerDependencies:
      - supports-color
    dev: false

  /emoji-regex@8.0.0:
    resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
    dev: false

  /emoji-regex@9.2.2:
    resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
    dev: false

  /end-of-stream@1.4.4:
    resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
    dependencies:
      once: 1.4.0
    dev: false

  /env-paths@2.2.1:
    resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
    engines: {node: '>=6'}
    dev: false

  /es-define-property@1.0.0:
    resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
    engines: {node: '>= 0.4'}
    dependencies:
      get-intrinsic: 1.2.4
    dev: false

  /es-errors@1.3.0:
    resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
    engines: {node: '>= 0.4'}
    dev: false

  /es6-error@4.1.1:
    resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
    requiresBuild: true
    dev: false
    optional: true

  /escalade@3.1.2:
    resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
    engines: {node: '>=6'}
    dev: false

  /escape-string-regexp@4.0.0:
    resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
    engines: {node: '>=10'}
    dev: false

  /eventemitter3@4.0.7:
    resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
    dev: false

  /extract-zip@2.0.1:
    resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==}
    engines: {node: '>= 10.17.0'}
    hasBin: true
    dependencies:
      debug: 4.3.4
      get-stream: 5.2.0
      yauzl: 2.10.0
    optionalDependencies:
      '@types/yauzl': 2.10.3
    transitivePeerDependencies:
      - supports-color
    dev: false

  /fd-slicer@1.1.0:
    resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
    dependencies:
      pend: 1.2.0
    dev: false

  /find-up@5.0.0:
    resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
    engines: {node: '>=10'}
    dependencies:
      locate-path: 6.0.0
      path-exists: 4.0.0
    dev: false

  /flat@5.0.2:
    resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
    hasBin: true
    dev: false

  /follow-redirects@1.15.6:
    resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
    engines: {node: '>=4.0'}
    peerDependencies:
      debug: '*'
    peerDependenciesMeta:
      debug:
        optional: true
    dev: false

  /foreground-child@3.3.1:
    resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
    engines: {node: '>=14'}
    dependencies:
      cross-spawn: 7.0.6
      signal-exit: 4.1.0
    dev: false

  /fs-extra@8.1.0:
    resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
    engines: {node: '>=6 <7 || >=8'}
    dependencies:
      graceful-fs: 4.2.11
      jsonfile: 4.0.0
      universalify: 0.1.2
    dev: false

  /fsevents@2.3.2:
    resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
    os: [darwin]
    requiresBuild: true
    dev: false
    optional: true

  /function-bind@1.1.2:
    resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
    dev: false

  /get-caller-file@2.0.5:
    resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
    engines: {node: 6.* || 8.* || >= 10.*}
    dev: false

  /get-func-name@2.0.2:
    resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
    dev: false

  /get-intrinsic@1.2.4:
    resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
    engines: {node: '>= 0.4'}
    dependencies:
      es-errors: 1.3.0
      function-bind: 1.1.2
      has-proto: 1.0.3
      has-symbols: 1.0.3
      hasown: 2.0.1
    dev: false

  /get-stream@5.2.0:
    resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
    engines: {node: '>=8'}
    dependencies:
      pump: 3.0.0
    dev: false

  /glob@10.5.0:
    resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
    deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
    hasBin: true
    dependencies:
      foreground-child: 3.3.1
      jackspeak: 3.4.3
      minimatch: 9.0.5
      minipass: 7.1.2
      package-json-from-dist: 1.0.1
      path-scurry: 1.11.1
    dev: false

  /global-agent@3.0.0:
    resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==}
    engines: {node: '>=10.0'}
    requiresBuild: true
    dependencies:
      boolean: 3.2.0
      es6-error: 4.1.1
      matcher: 3.0.0
      roarr: 2.15.4
      semver: 7.6.0
      serialize-error: 7.0.1
    dev: false
    optional: true

  /globalthis@1.0.3:
    resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
    engines: {node: '>= 0.4'}
    requiresBuild: true
    dependencies:
      define-properties: 1.2.1
    dev: false
    optional: true

  /gopd@1.0.1:
    resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
    dependencies:
      get-intrinsic: 1.2.4
    dev: false

  /got@11.8.6:
    resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==}
    engines: {node: '>=10.19.0'}
    dependencies:
      '@sindresorhus/is': 4.6.0
      '@szmarczak/http-timer': 4.0.6
      '@types/cacheable-request': 6.0.3
      '@types/responselike': 1.0.3
      cacheable-lookup: 5.0.4
      cacheable-request: 7.0.4
      decompress-response: 6.0.0
      http2-wrapper: 1.0.3
      lowercase-keys: 2.0.0
      p-cancelable: 2.1.1
      responselike: 2.0.1
    dev: false

  /graceful-fs@4.2.11:
    resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
    dev: false

  /has-flag@4.0.0:
    resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
    engines: {node: '>=8'}
    dev: false

  /has-property-descriptors@1.0.2:
    resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
    dependencies:
      es-define-property: 1.0.0
    dev: false

  /has-proto@1.0.3:
    resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
    engines: {node: '>= 0.4'}
    dev: false

  /has-symbols@1.0.3:
    resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
    engines: {node: '>= 0.4'}
    dev: false

  /hasown@2.0.1:
    resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==}
    engines: {node: '>= 0.4'}
    dependencies:
      function-bind: 1.1.2
    dev: false

  /he@1.2.0:
    resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
    hasBin: true
    dev: false

  /history@4.10.1:
    resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==}
    dependencies:
      '@babel/runtime': 7.23.9
      loose-envify: 1.4.0
      resolve-pathname: 3.0.0
      tiny-invariant: 1.3.2
      tiny-warning: 1.0.3
      value-equal: 1.0.1
    dev: false

  /hoist-non-react-statics@3.3.2:
    resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
    dependencies:
      react-is: 16.13.1
    dev: false

  /html-encoding-sniffer@3.0.0:
    resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==}
    engines: {node: '>=12'}
    dependencies:
      whatwg-encoding: 2.0.0
    dev: false

  /http-cache-semantics@4.1.1:
    resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
    dev: false

  /http-proxy@1.18.1:
    resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==}
    engines: {node: '>=8.0.0'}
    dependencies:
      eventemitter3: 4.0.7
      follow-redirects: 1.15.6
      requires-port: 1.0.0
    transitivePeerDependencies:
      - debug
    dev: false

  /http-server@14.1.1:
    resolution: {integrity: sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==}
    engines: {node: '>=12'}
    hasBin: true
    dependencies:
      basic-auth: 2.0.1
      chalk: 4.1.2
      corser: 2.0.1
      he: 1.2.0
      html-encoding-sniffer: 3.0.0
      http-proxy: 1.18.1
      mime: 1.6.0
      minimist: 1.2.8
      opener: 1.5.2
      portfinder: 1.0.38
      secure-compare: 3.0.1
      union: 0.5.0
      url-join: 4.0.1
    transitivePeerDependencies:
      - debug
      - supports-color
    dev: false

  /http2-wrapper@1.0.3:
    resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==}
    engines: {node: '>=10.19.0'}
    dependencies:
      quick-lru: 5.1.1
      resolve-alpn: 1.2.1
    dev: false

  /iconv-lite@0.6.3:
    resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
    engines: {node: '>=0.10.0'}
    dependencies:
      safer-buffer: 2.1.2
    dev: false

  /is-fullwidth-code-point@3.0.0:
    resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
    engines: {node: '>=8'}
    dev: false

  /is-path-inside@3.0.3:
    resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
    engines: {node: '>=8'}
    dev: false

  /is-plain-obj@2.1.0:
    resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==}
    engines: {node: '>=8'}
    dev: false

  /is-unicode-supported@0.1.0:
    resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
    engines: {node: '>=10'}
    dev: false

  /isarray@0.0.1:
    resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==}
    dev: false

  /isarray@2.0.5:
    resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
    dev: false

  /isexe@2.0.0:
    resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
    dev: false

  /jackspeak@3.4.3:
    resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
    dependencies:
      '@isaacs/cliui': 8.0.2
    optionalDependencies:
      '@pkgjs/parseargs': 0.11.0
    dev: false

  /js-base64@3.7.7:
    resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==}
    dev: false

  /js-tokens@4.0.0:
    resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
    dev: false

  /js-yaml@4.1.0:
    resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
    hasBin: true
    dependencies:
      argparse: 2.0.1
    dev: false

  /json-buffer@3.0.1:
    resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
    dev: false

  /json-stable-stringify@1.1.1:
    resolution: {integrity: sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==}
    engines: {node: '>= 0.4'}
    dependencies:
      call-bind: 1.0.7
      isarray: 2.0.5
      jsonify: 0.0.1
      object-keys: 1.1.1
    dev: false

  /json-stringify-safe@5.0.1:
    resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
    requiresBuild: true
    dev: false
    optional: true

  /jsonfile@4.0.0:
    resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
    optionalDependencies:
      graceful-fs: 4.2.11
    dev: false

  /jsonify@0.0.1:
    resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==}
    dev: false

  /just-extend@6.2.0:
    resolution: {integrity: sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==}
    dev: false

  /keyv@4.5.4:
    resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
    dependencies:
      json-buffer: 3.0.1
    dev: false

  /locate-path@6.0.0:
    resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
    engines: {node: '>=10'}
    dependencies:
      p-locate: 5.0.0
    dev: false

  /lodash.get@4.4.2:
    resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
    dev: false

  /log-symbols@4.1.0:
    resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
    engines: {node: '>=10'}
    dependencies:
      chalk: 4.1.2
      is-unicode-supported: 0.1.0
    dev: false

  /loose-envify@1.4.0:
    resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
    hasBin: true
    dependencies:
      js-tokens: 4.0.0
    dev: false

  /loupe@2.3.7:
    resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==}
    dependencies:
      get-func-name: 2.0.2
    dev: false

  /lowercase-keys@2.0.0:
    resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==}
    engines: {node: '>=8'}
    dev: false

  /lru-cache@10.4.3:
    resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
    dev: false

  /lru-cache@6.0.0:
    resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
    engines: {node: '>=10'}
    requiresBuild: true
    dependencies:
      yallist: 4.0.0
    dev: false
    optional: true

  /matcher@3.0.0:
    resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
    engines: {node: '>=10'}
    requiresBuild: true
    dependencies:
      escape-string-regexp: 4.0.0
    dev: false
    optional: true

  /mime@1.6.0:
    resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
    engines: {node: '>=4'}
    hasBin: true
    dev: false

  /mimic-response@1.0.1:
    resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==}
    engines: {node: '>=4'}
    dev: false

  /mimic-response@3.1.0:
    resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
    engines: {node: '>=10'}
    dev: false

  /minimatch@9.0.5:
    resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
    engines: {node: '>=16 || 14 >=14.17'}
    dependencies:
      brace-expansion: 2.0.1
    dev: false

  /minimist@1.2.8:
    resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
    dev: false

  /minipass@7.1.2:
    resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
    engines: {node: '>=16 || 14 >=14.17'}
    dev: false

  /mocha@11.7.5:
    resolution: {integrity: sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==}
    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
    hasBin: true
    dependencies:
      browser-stdout: 1.3.1
      chokidar: 4.0.3
      debug: 4.4.3(supports-color@8.1.1)
      diff: 7.0.0
      escape-string-regexp: 4.0.0
      find-up: 5.0.0
      glob: 10.5.0
      he: 1.2.0
      is-path-inside: 3.0.3
      js-yaml: 4.1.0
      log-symbols: 4.1.0
      minimatch: 9.0.5
      ms: 2.1.3
      picocolors: 1.1.1
      serialize-javascript: 6.0.2
      strip-json-comments: 3.1.1
      supports-color: 8.1.1
      workerpool: 9.3.4
      yargs: 17.7.2
      yargs-parser: 21.1.1
      yargs-unparser: 2.0.0
    dev: false

  /ms@2.1.2:
    resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
    dev: false

  /ms@2.1.3:
    resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
    dev: false

  /nise@6.0.0:
    resolution: {integrity: sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==}
    dependencies:
      '@sinonjs/commons': 3.0.1
      '@sinonjs/fake-timers': 11.2.2
      '@sinonjs/text-encoding': 0.7.2
      just-extend: 6.2.0
      path-to-regexp: 6.2.2
    dev: false

  /normalize-url@6.1.0:
    resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==}
    engines: {node: '>=10'}
    dev: false

  /object-assign@4.1.1:
    resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
    engines: {node: '>=0.10.0'}
    dev: false

  /object-inspect@1.13.1:
    resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==}
    dev: false

  /object-keys@1.1.1:
    resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
    engines: {node: '>= 0.4'}
    dev: false

  /once@1.4.0:
    resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
    dependencies:
      wrappy: 1.0.2
    dev: false

  /opener@1.5.2:
    resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==}
    hasBin: true
    dev: false

  /p-cancelable@2.1.1:
    resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==}
    engines: {node: '>=8'}
    dev: false

  /p-limit@3.1.0:
    resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
    engines: {node: '>=10'}
    dependencies:
      yocto-queue: 0.1.0
    dev: false

  /p-locate@5.0.0:
    resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
    engines: {node: '>=10'}
    dependencies:
      p-limit: 3.1.0
    dev: false

  /package-json-from-dist@1.0.1:
    resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
    dev: false

  /pako@1.0.11:
    resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
    dev: false

  /path-exists@4.0.0:
    resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
    engines: {node: '>=8'}
    dev: false

  /path-key@3.1.1:
    resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
    engines: {node: '>=8'}
    dev: false

  /path-scurry@1.11.1:
    resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
    engines: {node: '>=16 || 14 >=14.18'}
    dependencies:
      lru-cache: 10.4.3
      minipass: 7.1.2
    dev: false

  /path-to-regexp@1.8.0:
    resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==}
    dependencies:
      isarray: 0.0.1
    dev: false

  /path-to-regexp@6.2.2:
    resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==}
    dev: false

  /pathval@1.1.1:
    resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
    dev: false

  /pend@1.2.0:
    resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
    dev: false

  /picocolors@1.1.1:
    resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
    dev: false

  /playwright-core@1.58.2:
    resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==}
    engines: {node: '>=18'}
    hasBin: true
    dev: false

  /playwright@1.58.2:
    resolution: {integrity: sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==}
    engines: {node: '>=18'}
    hasBin: true
    dependencies:
      playwright-core: 1.58.2
    optionalDependencies:
      fsevents: 2.3.2
    dev: false

  /portfinder@1.0.38:
    resolution: {integrity: sha512-rEwq/ZHlJIKw++XtLAO8PPuOQA/zaPJOZJ37BVuN97nLpMJeuDVLVGRwbFoBgLudgdTMP2hdRJP++H+8QOA3vg==}
    engines: {node: '>= 10.12'}
    dependencies:
      async: 3.2.6
      debug: 4.4.3(supports-color@8.1.1)
    transitivePeerDependencies:
      - supports-color
    dev: false

  /progress@2.0.3:
    resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
    engines: {node: '>=0.4.0'}
    dev: false

  /prop-types@15.8.1:
    resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
    dependencies:
      loose-envify: 1.4.0
      object-assign: 4.1.1
      react-is: 16.13.1
    dev: false

  /pump@3.0.0:
    resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
    dependencies:
      end-of-stream: 1.4.4
      once: 1.4.0
    dev: false

  /qs@6.11.0:
    resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
    engines: {node: '>=0.6'}
    dependencies:
      side-channel: 1.0.5
    dev: false

  /quick-lru@5.1.1:
    resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
    engines: {node: '>=10'}
    dev: false

  /randombytes@2.1.0:
    resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
    dependencies:
      safe-buffer: 5.2.1
    dev: false

  /react-dom@16.14.0(react@16.14.0):
    resolution: {integrity: sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==}
    peerDependencies:
      react: ^16.14.0
    dependencies:
      loose-envify: 1.4.0
      object-assign: 4.1.1
      prop-types: 15.8.1
      react: 16.14.0
      scheduler: 0.19.1
    dev: false

  /react-is@16.13.1:
    resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
    dev: false

  /react-router-dom@5.3.4(react@16.14.0):
    resolution: {integrity: sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==}
    peerDependencies:
      react: '>=15'
    dependencies:
      '@babel/runtime': 7.23.9
      history: 4.10.1
      loose-envify: 1.4.0
      prop-types: 15.8.1
      react: 16.14.0
      react-router: 5.3.4(react@16.14.0)
      tiny-invariant: 1.3.2
      tiny-warning: 1.0.3
    dev: false

  /react-router@5.3.4(react@16.14.0):
    resolution: {integrity: sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==}
    peerDependencies:
      react: '>=15'
    dependencies:
      '@babel/runtime': 7.23.9
      history: 4.10.1
      hoist-non-react-statics: 3.3.2
      loose-envify: 1.4.0
      path-to-regexp: 1.8.0
      prop-types: 15.8.1
      react: 16.14.0
      react-is: 16.13.1
      tiny-invariant: 1.3.2
      tiny-warning: 1.0.3
    dev: false

  /react@16.14.0:
    resolution: {integrity: sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==}
    engines: {node: '>=0.10.0'}
    dependencies:
      loose-envify: 1.4.0
      object-assign: 4.1.1
      prop-types: 15.8.1
    dev: false

  /readdirp@4.1.2:
    resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
    engines: {node: '>= 14.18.0'}
    dev: false

  /regenerator-runtime@0.14.1:
    resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
    dev: false

  /require-directory@2.1.1:
    resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
    engines: {node: '>=0.10.0'}
    dev: false

  /requires-port@1.0.0:
    resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
    dev: false

  /resolve-alpn@1.2.1:
    resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
    dev: false

  /resolve-pathname@3.0.0:
    resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==}
    dev: false

  /responselike@2.0.1:
    resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==}
    dependencies:
      lowercase-keys: 2.0.0
    dev: false

  /roarr@2.15.4:
    resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==}
    engines: {node: '>=8.0'}
    requiresBuild: true
    dependencies:
      boolean: 3.2.0
      detect-node: 2.1.0
      globalthis: 1.0.3
      json-stringify-safe: 5.0.1
      semver-compare: 1.0.0
      sprintf-js: 1.1.3
    dev: false
    optional: true

  /safe-buffer@5.1.2:
    resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
    dev: false

  /safe-buffer@5.2.1:
    resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
    dev: false

  /safer-buffer@2.1.2:
    resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
    dev: false

  /scheduler@0.19.1:
    resolution: {integrity: sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==}
    dependencies:
      loose-envify: 1.4.0
      object-assign: 4.1.1
    dev: false

  /secure-compare@3.0.1:
    resolution: {integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==}
    dev: false

  /semver-compare@1.0.0:
    resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==}
    requiresBuild: true
    dev: false
    optional: true

  /semver@6.3.1:
    resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
    hasBin: true
    dev: false

  /semver@7.6.0:
    resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==}
    engines: {node: '>=10'}
    hasBin: true
    requiresBuild: true
    dependencies:
      lru-cache: 6.0.0
    dev: false
    optional: true

  /serialize-error@7.0.1:
    resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
    engines: {node: '>=10'}
    requiresBuild: true
    dependencies:
      type-fest: 0.13.1
    dev: false
    optional: true

  /serialize-javascript@6.0.2:
    resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
    dependencies:
      randombytes: 2.1.0
    dev: false

  /set-function-length@1.2.1:
    resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==}
    engines: {node: '>= 0.4'}
    dependencies:
      define-data-property: 1.1.4
      es-errors: 1.3.0
      function-bind: 1.1.2
      get-intrinsic: 1.2.4
      gopd: 1.0.1
      has-property-descriptors: 1.0.2
    dev: false

  /shebang-command@2.0.0:
    resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
    engines: {node: '>=8'}
    dependencies:
      shebang-regex: 3.0.0
    dev: false

  /shebang-regex@3.0.0:
    resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
    engines: {node: '>=8'}
    dev: false

  /side-channel@1.0.5:
    resolution: {integrity: sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==}
    engines: {node: '>= 0.4'}
    dependencies:
      call-bind: 1.0.7
      es-errors: 1.3.0
      get-intrinsic: 1.2.4
      object-inspect: 1.13.1
    dev: false

  /signal-exit@4.1.0:
    resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
    engines: {node: '>=14'}
    dev: false

  /sinon@18.0.0:
    resolution: {integrity: sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==}
    dependencies:
      '@sinonjs/commons': 3.0.1
      '@sinonjs/fake-timers': 11.2.2
      '@sinonjs/samsam': 8.0.0
      diff: 5.2.0
      nise: 6.0.0
      supports-color: 7.2.0
    dev: false

  /source-map-support@0.5.21:
    resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
    dependencies:
      buffer-from: 1.1.2
      source-map: 0.6.1
    dev: false

  /source-map@0.6.1:
    resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
    engines: {node: '>=0.10.0'}
    dev: false

  /sprintf-js@1.1.3:
    resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
    requiresBuild: true
    dev: false
    optional: true

  /string-width@4.2.3:
    resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
    engines: {node: '>=8'}
    dependencies:
      emoji-regex: 8.0.0
      is-fullwidth-code-point: 3.0.0
      strip-ansi: 6.0.1
    dev: false

  /string-width@5.1.2:
    resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
    engines: {node: '>=12'}
    dependencies:
      eastasianwidth: 0.2.0
      emoji-regex: 9.2.2
      strip-ansi: 7.1.2
    dev: false

  /strip-ansi@6.0.1:
    resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
    engines: {node: '>=8'}
    dependencies:
      ansi-regex: 5.0.1
    dev: false

  /strip-ansi@7.1.2:
    resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
    engines: {node: '>=12'}
    dependencies:
      ansi-regex: 6.2.2
    dev: false

  /strip-json-comments@3.1.1:
    resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
    engines: {node: '>=8'}
    dev: false

  /sumchecker@3.0.1:
    resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==}
    engines: {node: '>= 8.0'}
    dependencies:
      debug: 4.3.4
    transitivePeerDependencies:
      - supports-color
    dev: false

  /supports-color@7.2.0:
    resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
    engines: {node: '>=8'}
    dependencies:
      has-flag: 4.0.0
    dev: false

  /supports-color@8.1.1:
    resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
    engines: {node: '>=10'}
    dependencies:
      has-flag: 4.0.0
    dev: false

  /tiny-invariant@1.3.2:
    resolution: {integrity: sha512-oLXoWt7bk7SI3REp16Hesm0kTBTErhk+FWTvuujYMlIbX42bb3yLN98T3OyzFNkZ3WAjVYDL4sWykCR6kD2mqQ==}
    dev: false

  /tiny-warning@1.0.3:
    resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
    dev: false

  /type-detect@4.0.8:
    resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
    engines: {node: '>=4'}
    dev: false

  /type-fest@0.13.1:
    resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
    engines: {node: '>=10'}
    requiresBuild: true
    dev: false
    optional: true

  /typescript@5.9.3:
    resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
    engines: {node: '>=14.17'}
    hasBin: true
    dev: false

  /undici-types@5.26.5:
    resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
    dev: false

  /undici-types@6.21.0:
    resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
    dev: false

  /union@0.5.0:
    resolution: {integrity: sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==}
    engines: {node: '>= 0.8.0'}
    dependencies:
      qs: 6.11.0
    dev: false

  /universalify@0.1.2:
    resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
    engines: {node: '>= 4.0.0'}
    dev: false

  /url-join@4.0.1:
    resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==}
    dev: false

  /use-sync-external-store@1.6.0(react@16.14.0):
    resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==}
    peerDependencies:
      react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
    dependencies:
      react: 16.14.0
    dev: false

  /uuid@8.3.2:
    resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
    hasBin: true
    dev: false

  /value-equal@1.0.1:
    resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==}
    dev: false

  /whatwg-encoding@2.0.0:
    resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==}
    engines: {node: '>=12'}
    deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation
    dependencies:
      iconv-lite: 0.6.3
    dev: false

  /which@2.0.2:
    resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
    engines: {node: '>= 8'}
    hasBin: true
    dependencies:
      isexe: 2.0.0
    dev: false

  /workerpool@9.3.4:
    resolution: {integrity: sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==}
    dev: false

  /wrap-ansi@7.0.0:
    resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
    engines: {node: '>=10'}
    dependencies:
      ansi-styles: 4.3.0
      string-width: 4.2.3
      strip-ansi: 6.0.1
    dev: false

  /wrap-ansi@8.1.0:
    resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
    engines: {node: '>=12'}
    dependencies:
      ansi-styles: 6.2.3
      string-width: 5.1.2
      strip-ansi: 7.1.2
    dev: false

  /wrappy@1.0.2:
    resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
    dev: false

  /y18n@5.0.8:
    resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
    engines: {node: '>=10'}
    dev: false

  /yallist@4.0.0:
    resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
    requiresBuild: true
    dev: false
    optional: true

  /yargs-parser@21.1.1:
    resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
    engines: {node: '>=12'}
    dev: false

  /yargs-unparser@2.0.0:
    resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==}
    engines: {node: '>=10'}
    dependencies:
      camelcase: 6.3.0
      decamelize: 4.0.0
      flat: 5.0.2
      is-plain-obj: 2.1.0
    dev: false

  /yargs@17.7.2:
    resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
    engines: {node: '>=12'}
    dependencies:
      cliui: 8.0.1
      escalade: 3.1.2
      get-caller-file: 2.0.5
      require-directory: 2.1.1
      string-width: 4.2.3
      y18n: 5.0.8
      yargs-parser: 21.1.1
    dev: false

  /yauzl@2.10.0:
    resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
    dependencies:
      buffer-crc32: 0.2.13
      fd-slicer: 1.1.0
    dev: false

  /yocto-queue@0.1.0:
    resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
    engines: {node: '>=10'}
    dev: false

  /zustand@4.5.7(@types/react@16.14.56)(react@16.14.0):
    resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==}
    engines: {node: '>=12.7.0'}
    peerDependencies:
      '@types/react': '>=16.8'
      immer: '>=9.0.6'
      react: '>=16.8'
    peerDependenciesMeta:
      '@types/react':
        optional: true
      immer:
        optional: true
      react:
        optional: true
    dependencies:
      '@types/react': 16.14.56
      react: 16.14.0
      use-sync-external-store: 1.6.0(react@16.14.0)
    dev: false

---

## File: tsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "#asciiflow/*": ["*", "bazel-bin/*", "bazel-genfiles/*"],
    },
    "module": "ESNext",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "noImplicitThis": true,
    "preserveConstEnums": true,
    "removeComments": true,
    "target": "ESNext",
    "sourceMap": true,
    "skipLibCheck": true,
    "jsx": "react",
    "lib": ["es2022", "dom"],
    "esModuleInterop": true,
    "declaration": true,
    "strictPropertyInitialization": false
  },
  "exclude": ["bazel-*", "node_modules"]
}

---

## File: tslint.json

{
  "extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
  "rules": {
    "object-literal-sort-keys": false,
    "max-classes-per-file": [false, 1],
    "no-floating-promises": true,
    "jsx-no-lambda": false,
    "no-empty": false
  }
}

---

## File: e2e/package.json

{
  "type": "commonjs"
}

---

## File: .github/workflows/deploy.yaml

name: Deploy

on:
  push:
    branches:
      - main
  release:
    types: [published]

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Bazelisk
        run: |
          sudo curl -fsSL -o /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64
          sudo chmod +x /usr/local/bin/bazel

      - name: Build the site
        run: bazel build site/... --remote_cache= --bes_backend= --bes_results_url= && cp -r --dereference bazel-bin/site ./deploy
        timeout-minutes: 10

      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: site
          path: ./deploy

  deploy-beta:
    name: Deploy to beta
    needs: build
    if: github.event_name == 'push'
    runs-on: ubuntu-latest
    environment: deploy
    steps:
      - name: Download build artifact
        uses: actions/download-artifact@v4
        with:
          name: site
          path: ./deploy

      - name: Publish to Cloudflare (beta)
        uses: cloudflare/pages-action@1
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: 4aa13cc00192d0927df8194260cb2ce8
          projectName: asciiflow
          directory: ./deploy
          gitHubToken: ${{ secrets.GITHUB_TOKEN }}
          branch: main

  deploy-prod:
    name: Deploy to production
    needs: build
    if: github.event_name == 'release'
    runs-on: ubuntu-latest
    environment: deploy
    steps:
      - name: Download build artifact
        uses: actions/download-artifact@v4
        with:
          name: site
          path: ./deploy

      - name: Publish to Cloudflare (production)
        uses: cloudflare/pages-action@1
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: 4aa13cc00192d0927df8194260cb2ce8
          projectName: asciiflow
          directory: ./deploy
          gitHubToken: ${{ secrets.GITHUB_TOKEN }}
          branch: production

---

## File: .github/workflows/test.yaml

name: Test

on: pull_request

jobs:
  test:
    name: Test and build
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Bazelisk
        run: |
          sudo curl -fsSL -o /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64
          sudo chmod +x /usr/local/bin/bazel

      - name: Install Playwright Chromium
        run: npx playwright@1.58.2 install --with-deps chromium

      - name: Run tests and build
        run: bazel test //common:all //client:all //e2e:all --remote_cache= --bes_backend= --bes_results_url= && bazel build //client:site --remote_cache= --bes_backend= --bes_results_url=
        timeout-minutes: 10

--- METRICS ---
- Files Extracted: 9
- Estimated Token Budget: ~33667 tokens
- Recency Window: Active (< 180 days)
- Canonical Reference: https://codewiki.google/github.com/lewish/asciiflow
