commit 93b060bc8b681bceca421ee20954940e893216af Author: jmcqueen Date: Mon Jul 6 14:48:51 2026 -0400 Modernize bot to Node.js 22 with modular architecture and remote SIW agent - Refactor monolithic index.js (2646 lines) into src/{webex,integrations, cards,flows,commands,services} modules; replace node-fetch/form-data with native fetch/FormData; move all secrets to .env via dotenv - Add dockerized remote SIW agent (docker/remote-agent/) with cross-arch buildx packaging (arm64 Mac -> linux/amd64), idempotent install.sh deploy bundle, and docker-free ZIP inspector for arch verification - Bot hosts a WebSocket server; agent proxies SIW requests with a per-request insecure:true flag, replacing the process-wide NODE_TLS_REJECT_UNAUTHORIZED bypass - Add ESLint flat config + Prettier, rewrite Dockerfile as non-root multi-stage node:22-alpine build, README covering setup / deploy / remote agent workflow - Fix parseStoreArg to read trigger.prompt correctly (was indexing past the framework's post-match slice); register /help as regex (string matcher only compares the first token); switch catch-all to /.+/ (previous /.*/gim was stateful due to the g flag); remove /fixDisplayNames command and its flow/card Co-authored-by: Cursor diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4f58e19 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,44 @@ +.git +.gitignore +.dockerignore + +# Dependencies (installed inside the image) +node_modules +npm-debug.log* + +# Secrets and local runtime state +.env +.env.* +config.json +config/wbxTokens.json +config/google-service-account.json +config/*-service-account.json +googleData.json +*.pem +*.key + +# Legacy top-level scripts (deleted after refactor but ignored defensively) +get911.js +getMeeting.js +phoneFix.js +storeAddress.js + +# Local scripts/tooling not needed at runtime +scripts/ +eslint.config.js +.prettierrc.json +.prettierignore + +# Remote-agent packaging (its own Dockerfile / image; not part of the bot image) +docker/ + +# Docs and generated output +*.md +*.log +*.zip +*.csv + +# OS / editor cruft +.DS_Store +.vscode/ +.idea/ diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c4d0ea7 --- /dev/null +++ b/.env.example @@ -0,0 +1,50 @@ +# Copy this file to .env and fill in real values. +# .env is git-ignored. NEVER commit real secrets. + +# --- Webex bot (webex-node-bot-framework) --- +WEBEX_BOT_TOKEN=your-webex-bot-token +WEBEX_BOT_NAME=AEO Call Provisioning +WEBEX_BOT_USERNAME=aeoCallProvisioning@webex.bot +WEBEX_BOT_ID=your-webex-bot-id + +# --- Webex service account (integration used for admin API calls) --- +WEBEX_SVC_CLIENT_ID=your-webex-integration-client-id +WEBEX_SVC_CLIENT_SECRET=your-webex-integration-client-secret + +# Path to the JSON file that persists the service-account access/refresh tokens. +# Created and rewritten automatically by the token-refresh cron. +WEBEX_TOKEN_STORE=./config/wbxTokens.json + +# --- Twilio (phone number validation) --- +TWILIO_ACCOUNT_SID=your-twilio-account-sid +TWILIO_AUTH_TOKEN=your-twilio-auth-token + +# --- Store Info Web (SIW) --- +# SIW requests are proxied through the on-prem remote agent (see WS_* below), +# so the base URL and credentials are forwarded to the agent per-request. This +# bot never talks to SIW directly. +SIW_BASE_URL=https://storeinfoweb-prod.ae.com +SIW_USERNAME=your-siw-user +SIW_PASSWORD=your-siw-password + +# --- Remote agent WebSocket bridge --- +# This bot listens on WS_PORT; the on-prem agent (a second instance of the +# netanalyzer remoteAgent.js) dials in with WS_URL=wss://.../ and this token +# as its Bearer credential. Rotate WS_TOKEN with any high-entropy string. +WS_PORT=8080 +WS_TOKEN=change-me-to-a-long-random-string + +# --- Google --- +# Simple REST API key used by Address Validation + Time Zone endpoints. +GOOGLE_API_KEY=your-google-api-key + +# Optional. Path to a Google service-account JSON key file (the one shaped +# like { type: "service_account", private_key: "-----BEGIN...", ... }). +# Not required for the REST calls above, but standard for any future code +# that uses google-auth-library / googleapis. Keep the file itself outside +# of git (config/google-service-account.json is already ignored). +GOOGLE_APPLICATION_CREDENTIALS=./config/google-service-account.json + +# --- Runtime --- +NODE_ENV=production +LOG_LEVEL=info diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8cac650 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +# Dependencies +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Secrets and local config +.env +.env.local +.env.*.local +config.json +config/wbxTokens.json +config/google-service-account.json +config/*-service-account.json +googleData.json +*.pem +*.key + +# Runtime artifacts +*.log +buildlogs.log + +# Generated CSV outputs (from scripts/generate911Csv.js) +buildingFile.csv +locationFile.csv + +# Archives +*.zip + +# Remote agent packaging output (produced by docker/remote-agent/package.sh) +docker/remote-agent/dist/ +docker/remote-agent/.env + +# OS / editor cruft +.DS_Store +Thumbs.db +.idea/ +.vscode/ +*.swp diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..9f9b6ad --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +node_modules/ +greetings/ +buildingFile.csv +locationFile.csv +package-lock.json +config/wbxTokens.json diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..7456336 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,8 @@ +{ + "singleQuote": true, + "tabWidth": 4, + "printWidth": 100, + "trailingComma": "all", + "semi": true, + "arrowParens": "always" +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fd75802 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +# syntax=docker/dockerfile:1.7 + +# --- build stage: install production dependencies only --- +FROM node:22-alpine AS deps +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm ci --omit=dev --no-audit --no-fund + +# --- runtime stage: minimal image with just what's needed to run --- +FROM node:22-alpine AS runtime +ENV NODE_ENV=production +WORKDIR /app + +# Bring in dependencies (owned by the built-in `node` user). +COPY --from=deps --chown=node:node /app/node_modules ./node_modules + +# Application code. +COPY --chown=node:node package.json package-lock.json ./ +COPY --chown=node:node src ./src +COPY --chown=node:node greetings ./greetings + +# Directory the token-refresh cron writes to. Mount a volume here in prod. +RUN mkdir -p /app/config && chown node:node /app/config + +# WebSocket port the on-prem SIW agent connects back to. Override at runtime +# via -e WS_PORT and -p host:container. +EXPOSE 8080 + +USER node +CMD ["node", "src/index.js"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..42576a5 --- /dev/null +++ b/README.md @@ -0,0 +1,197 @@ +# wbxStoreProvision + +Webex Calling provisioning bot for AEO retail stores. Runs as a Webex bot and +exposes slash commands that create Webex locations, attach phone numbers, upload +greetings, build auto-attendants, and clean up user licensing. + +## Requirements + +- Node.js 20+ (Docker image uses `node:22-alpine`). +- A Webex bot token, a Webex integration (service account) with the scopes + currently used by admin API calls, a Twilio lookup account, an SIW basic-auth + user, and a Google API key with Address Validation + Time Zone enabled. +- An on-prem host that can reach Store Info Web, to run the remote agent + (see [Remote SIW agent](#remote-siw-agent) below). +- Optional: a Google service-account JSON key. Only the REST API key is + required today, but if/when you add code that uses `google-auth-library`, + save the JSON at `config/google-service-account.json` and set + `GOOGLE_APPLICATION_CREDENTIALS` in `.env` to point at it. The file is + git-ignored. + +## Local setup + +```bash +cp .env.example .env +# Edit .env with real values +npm install +npm start +``` + +The token-refresh cron reads and writes `config/wbxTokens.json` (path +configurable via `WEBEX_TOKEN_STORE`). Seed this file once with a valid +`access_token`, `refresh_token`, and `expiresOn`; the process will keep it up to +date from then on. + +## Scripts + +| npm script | What it does | +| -------------------------- | ----------------------------------------------------------- | +| `npm start` | Run the bot. | +| `npm run dev` | Run with `node --watch` for local iteration. | +| `npm run lint` | ESLint (flat config) across the tree. | +| `npm run format` | Prettier write. | +| `npm run generate-911-csv` | Rebuild `buildingFile.csv` + `locationFile.csv` from SIW. | +| `npm run fix-store-phones` | Normalize licensing + default meeting site for store users. | + +## Docker + +```bash +docker build -t wbxcallprov . +docker run --rm --env-file .env \ + -p 8080:8080 \ + -v "$(pwd)/config:/app/config" \ + wbxcallprov +``` + +The volume mount preserves `config/wbxTokens.json` across restarts so the +refresh cron doesn't lose state. The `-p 8080:8080` publishes the WebSocket +port so the remote SIW agent can connect back to the bot. + +## Remote SIW agent + +Store Info Web only accepts connections from inside the corporate network, +but the bot runs in the cloud. To bridge the gap, the bot hosts a +WebSocket server; a small on-prem agent dials in and proxies HTTP requests +back and forth. + +The agent itself is intentionally generic — it just proxies whatever +`{method, url, headers, auth, body}` payload arrives — and lives in +[`docker/remote-agent/`](docker/remote-agent) as a self-contained Docker +bundle you can build here and ship to the on-prem host. + +Once the agent is connected, the bot logs `Remote agent connected` and any +`/buildStore`, `/stageStore`, `/migrateStore` command will succeed. If the +agent is not connected, the SIW-dependent commands fail immediately with +`No remote SIW agent connected` rather than silently timing out. + +### Deploying the agent + +The `docker/remote-agent/` folder produces a fully offline-installable ZIP +(image tarball + `install.sh` + `docker-compose.yml`). The workflow is the +same as netanalyzer's bundle — same layout, same operator playbook — and +the two bundles use distinct image tags and container names +(`wbxprov-remote-agent` vs `sha-remote-agent`) so a single on-prem host +can run both agents side by side. + +Build the bundle (on your workstation, or in CI): + +```bash +# Default: linux/amd64 (typical Rocky/RHEL/Ubuntu server) +npm run agent:package + +# Or explicitly, with a different target arch: +./docker/remote-agent/package.sh --platform linux/arm64 +``` + +That produces `docker/remote-agent/dist/wbxprov-remote-agent-.zip`. +Transfer it to the on-prem host, then: + +```bash +unzip wbxprov-remote-agent-.zip +cd wbxprov-remote-agent- +./install.sh # first run: seeds .env and stops +vi .env # set WS_URL + WS_TOKEN +./install.sh # second run: starts the container +docker compose logs -f # tail the agent's connection status +``` + +Set `WS_URL` to the bot's public WebSocket endpoint (e.g. +`wss://your-wbxstoreprovision-host:8080`) and `WS_TOKEN` to the same value +you configured for `WS_TOKEN` in the bot's `.env`. See +[`docker/remote-agent/README.md`](docker/remote-agent/README.md) for build +details and [`docker/remote-agent/deploy/README.md`](docker/remote-agent/deploy/README.md) +for the full operator guide (upgrades, troubleshooting, coexistence with +`sha-remote-agent`). + +## Bot commands + +Registered in [src/commands](src/commands): + +- `/buildStore ` — full green-field build (create location, calling, + greeting, attach user, license cleanup). +- `/stageStore ` — pre-migration setup: same as buildStore but + without phone-number attachment or licensing cleanup. +- `/migrateStore ` — cut-over for a staged store: attach the phone + number, set caller ID, create the auto-attendant, finalize licensing. +- `/storeinfo ` — show current Webex info for the store user + (`ae<5-digit>@ae.com`). +- `/userinfo ` — show current Webex info for any user by email. +- `/help` — bot's own help output. + +Card confirmations post `attachmentAction` events, dispatched in +[src/commands/attachmentActions.js](src/commands/attachmentActions.js). + +## Architecture + +``` +src/ + index.js bot bootstrap, cron, command wiring (~70 lines) + config.js dotenv loading + validation + constants.js org-scoped IDs (route groups, licenses, greetings, ...) + logger.js small level-aware logger + http.js fetch wrapper (rate limit + optional SIW TLS agent) + webex/ all Webex API calls, one module per resource family + integrations/ SIW / Twilio / Google + cards/ Adaptive Card builders + flows/ multi-step provisioning (build, stage, migrate, ...) + commands/ framework.hears handlers + attachmentAction dispatch +scripts/ one-off maintenance scripts (911 CSV, phone fix-up) +greetings/ WAV files uploaded as location announcements +config/wbxTokens.json persistent service-account token cache (git-ignored) +``` + +Data flow for a store provisioning: + +```mermaid +flowchart LR + User[Webex user] -->|/buildStore 1234| Commands[commands/*] + Commands --> SIW[integrations/siw.js] + Commands --> Users[webex/users.js] + Commands --> Card[cards/storeInfoCard.js] + Card -->|confirm| Attachment[attachmentActions.js] + Attachment --> Flow[flows/buildStore.js] + Flow --> Locations[webex/locations.js] + Flow --> Devices[webex/devices.js] + Flow --> Announce[webex/announcements.js] + Flow --> License[webex/licensing.js] + subgraph background + Cron[node-cron every 60s] --> Auth[webex/auth.js] + Auth --> Tokens[(config/wbxTokens.json)] + end +``` + +## Security notes + +- `.env` and `config/wbxTokens.json` are git-ignored. Never commit them. +- `NODE_TLS_REJECT_UNAUTHORIZED=0` is no longer set globally. If SIW's TLS + cert cannot be verified from your host, set `ALLOW_INSECURE_SIW_TLS=true`; + the insecure dispatcher is then scoped to SIW requests only. +- Concurrent Webex token refreshes are collapsed into a single in-flight + refresh in [src/webex/auth.js](src/webex/auth.js). + +### One-time secret rotation + +The pre-refactor `config.json` and `getMeeting.js` stored real secrets in +plain text on disk. Regardless of git history, treat the following as +**exposed** and rotate them at their source: + +- Webex bot token (`WEBEX_BOT_TOKEN`) +- Webex integration client secret + service-account access / refresh tokens + (`WEBEX_SVC_CLIENT_SECRET`, plus everything in `config/wbxTokens.json`) +- Twilio auth token (`TWILIO_AUTH_TOKEN`) +- SIW basic-auth password (`SIW_PASSWORD`) +- Google API key (`GOOGLE_API_KEY`) and any service-account private key that + was previously in `config.json` + +After rotating, populate the new values in `.env` and seed a fresh +`config/wbxTokens.json` with the new access/refresh token pair. diff --git a/docker/remote-agent/.env.example b/docker/remote-agent/.env.example new file mode 100644 index 0000000..1739ea8 --- /dev/null +++ b/docker/remote-agent/.env.example @@ -0,0 +1,16 @@ +# ============================================================================= +# wbxStoreProvision Remote Agent — Environment +# Copy this file to `.env` (next to docker-compose.yml) and fill in the +# values. NEVER commit .env — the .gitignore already excludes it. +# ============================================================================= + +# WebSocket URL of the main wbxStoreProvision bot. Use `wss://` if the bot +# is reverse-proxied through TLS; `ws://host:port` for a direct connection. +# Do NOT put the token in a `?token=` query parameter — WS_TOKEN below is +# sent as an Authorization: Bearer header instead. +WS_URL=wss://wbxstoreprovision.example.com/ws + +# Shared secret that must match WS_TOKEN on the bot side (the value in the +# bot's own .env). Generate a strong random value once and rotate it if you +# suspect it's been exposed. +WS_TOKEN=change_me_to_a_long_random_value diff --git a/docker/remote-agent/Dockerfile b/docker/remote-agent/Dockerfile new file mode 100644 index 0000000..67f0a97 --- /dev/null +++ b/docker/remote-agent/Dockerfile @@ -0,0 +1,54 @@ +# syntax=docker/dockerfile:1.7 + +# ============================================================================ +# wbxStoreProvision — Remote Agent +# ---------------------------------------------------------------------------- +# Tiny WebSocket client that proxies HTTP requests (Store Info Web today, +# anything else in the future) from an internal network back to the main +# wbxStoreProvision bot. Ships as a standalone container so it can run +# inside the segmented network where SIW lives. +# +# Build context is docker/remote-agent (self-contained — the agent doesn't +# need any of the bot's source or dependencies). +# +# Build: +# docker build -f docker/remote-agent/Dockerfile \ +# -t wbxprov-remote-agent:latest docker/remote-agent +# +# Run: +# docker run --rm -it \ +# --env-file docker/remote-agent/.env \ +# --name wbxprov-remote-agent \ +# wbxprov-remote-agent:latest +# ============================================================================ + +# ---- Stage 1: dependencies ------------------------------------------------ +FROM node:22-alpine AS deps + +WORKDIR /app + +# Minimal manifest: ws + axios + dotenv. No lockfile — three stable deps. +COPY package.json ./package.json +RUN npm install --omit=dev --no-audit --no-fund && npm cache clean --force + +# ---- Stage 2: runtime ----------------------------------------------------- +FROM node:22-alpine AS runtime + +# tini reaps zombies and forwards signals correctly so `docker stop` reaches +# Node's SIGTERM handler for a clean websocket close. +RUN apk add --no-cache tini + +WORKDIR /app +USER node + +COPY --chown=node:node --from=deps /app/node_modules ./node_modules +COPY --chown=node:node package.json ./package.json +COPY --chown=node:node remoteAgent.js ./remoteAgent.js + +ENV NODE_ENV=production + +# The agent is a WebSocket CLIENT — it doesn't listen on any port, so we +# intentionally skip EXPOSE. + +ENTRYPOINT ["/sbin/tini", "--"] +CMD ["node", "remoteAgent.js"] diff --git a/docker/remote-agent/README.md b/docker/remote-agent/README.md new file mode 100644 index 0000000..7818f27 --- /dev/null +++ b/docker/remote-agent/README.md @@ -0,0 +1,152 @@ +# wbxStoreProvision Remote Agent — Build & Package + +This directory produces a self-contained, offline-installable Docker bundle +for the wbxStoreProvision remote agent. The agent is a tiny WebSocket +client that runs inside a segmented (store / on-prem) network and proxies +HTTP requests from the main bot back to Store Info Web. + +The layout mirrors the equivalent bundle in the `netanalyzer` repo so the +same operator playbook applies. Both bundles use distinct image tags and +container names (`wbxprov-remote-agent` vs `sha-remote-agent`), so a single +on-prem host can run both agents side by side without conflict. + +## Layout + +``` +docker/remote-agent/ +├── Dockerfile build definition (node:22-alpine + tini, non-root) +├── docker-compose.yml build-from-source compose (dev / rebuild use only) +├── package.json the agent's own package manifest (ws + axios + dotenv) +├── package.sh produces the shippable ZIP under dist/ +├── inspect-bundle.sh docker-free arch/OS check on any built ZIP +├── remoteAgent.js the agent itself — proxies WS → HTTP +├── .env.example template consumed at deploy time +├── deploy/ +│ ├── docker-compose.yml runtime-only compose (used inside the ZIP) +│ ├── install.sh idempotent installer bundled into the ZIP +│ └── README.md operator-facing README bundled into the ZIP +└── dist/ produced by package.sh (git-ignored) +``` + +## Build & package a bundle + +From the repo root, or the `docker/remote-agent/` directory: + +```bash +# Default: build for linux/amd64 (typical Rocky/RHEL/Ubuntu servers) +npm run agent:package +# or explicitly: ./docker/remote-agent/package.sh + +# ARM Linux target (e.g. Raspberry Pi, ARM-based server) +./docker/remote-agent/package.sh --platform linux/arm64 + +# Override the version tag +./docker/remote-agent/package.sh --tag 1.0.1 + +# Preflight only — verify the build environment without actually building. +# Useful the first time you set up a new machine. +npm run agent:check +``` + +Output: `docker/remote-agent/dist/wbxprov-remote-agent-.zip`. + +### How cross-arch builds (arm64 Mac → linux/amd64) are guaranteed + +Building an `x86_64` Linux image from an Apple Silicon Mac is the single +easiest way to silently ship a broken bundle, so the script defends against +that in **four independent layers**: + +1. **Dedicated `docker-container` builder.** The default buildx builder on + Docker Desktop uses the `docker` driver, which is pinned to the daemon's + native architecture and will happily *ignore* `--platform`. The script + creates (and, if it finds a mis-driver builder with the same name, + *re-creates*) a `wbxprov-remote-agent-builder` using the + `docker-container` driver, which spins up an isolated BuildKit instance + that actually honors `--platform`. +2. **`binfmt` handlers.** When cross-building, the script best-effort + registers QEMU handlers for the target arch via `tonistiigi/binfmt`. + Docker Desktop usually has these; Colima / plain Docker Engine often + don't. +3. **`docker image inspect` check after build.** Reads the image out of the + local daemon and refuses to proceed if `Architecture` doesn't match the + requested `--platform`. +4. **`inspect-bundle.sh` on the final ZIP.** Independent, docker-free check + that reads the image config JSON directly out of the tarball inside the + ZIP. If this passes, the ZIP is provably correct regardless of anything + the local daemon may have said. + +If any layer detects a mismatch, `package.sh` exits non-zero and prints +the exact rebuild command. You cannot accidentally ship an arm64 bundle to +an amd64 host. + +### Verify a ZIP after the fact (no docker required) + +```bash +# Auto-detects the newest ZIP in dist/: +npm run agent:inspect + +# Or point it at a specific bundle: +./docker/remote-agent/inspect-bundle.sh path/to/wbxprov-remote-agent-1.0.0.zip + +# Enforce expectations (exits non-zero if wrong): +EXPECTED_ARCH=amd64 EXPECTED_OS=linux npm run agent:inspect +``` + +This works on any machine with `python3` + `unzip` — no Docker daemon +required — so you can verify a bundle on the Linux target host itself +before running `./install.sh`. + +### Requirements on the build host + +- Docker with the buildx plugin (Docker Desktop includes it out of the box). +- `zip`, `node`, `python3`, and either `sha256sum` or `shasum`. + +## Deploy the bundle on the remote host + +Transfer the ZIP produced above to the target host, then: + +```bash +unzip wbxprov-remote-agent-.zip +cd wbxprov-remote-agent- +./install.sh +``` + +`install.sh` will: + +1. Verify the SHA-256 checksum against `SHA256SUMS`. +2. `docker load` the image tarball. +3. Sanity-check the image architecture matches the host. +4. On first run: copy `.env.example` → `.env` and stop, asking you to fill + in `WS_URL` (the bot's public WebSocket endpoint) and `WS_TOKEN` + (matching the value in the bot's `.env`). +5. On the second run: `docker compose up -d` to start the container. + +See `deploy/README.md` for the full operator-facing guide (upgrades, +troubleshooting, logs). + +## Configuring the bot side + +The bot's `.env` needs matching values: + +``` +WS_PORT=8080 # what the bot's WebSocket server listens on +WS_TOKEN= +``` + +Make sure whatever public URL fronts the bot (reverse proxy, ingress, etc.) +maps `/ws` (or wherever `WS_URL` in the agent's `.env` points) through to +`WS_PORT` on the bot container. + +## Coexisting with the netanalyzer agent + +The two bundles are cleanly separated: + +| | wbxStoreProvision | netanalyzer | +| ---------------------- | --------------------------------- | ---------------------------- | +| Image tag | `wbxprov-remote-agent:` | `sha-remote-agent:` | +| Container name | `wbxprov-remote-agent` | `sha-remote-agent` | +| Deploy folder | `wbxprov-remote-agent-/` | `sha-remote-agent-/`| +| `.env` variables | `WS_URL`, `WS_TOKEN` | `WS_URL`, `WS_TOKEN` | + +Each has its own `.env` inside its own folder pointing at its own server, so +there's no shared state between them. diff --git a/docker/remote-agent/deploy/README.md b/docker/remote-agent/deploy/README.md new file mode 100644 index 0000000..5153ed3 --- /dev/null +++ b/docker/remote-agent/deploy/README.md @@ -0,0 +1,136 @@ +# wbxStoreProvision Remote Agent — Deploy Bundle + +This ZIP is a self-contained deployment bundle for the wbxStoreProvision +remote agent. Extract it, run `install.sh`, fill in your `.env`, and the +agent will start as a Docker container. + +## What's in the bundle + +| File | Purpose | +| --- | --- | +| `wbxprov-remote-agent-.tar.gz` | The Docker image, saved via `docker save`. | +| `docker-compose.yml` | Runtime-only compose file (no build step; references the loaded image). | +| `install.sh` | Verifies checksum, loads the image, seeds `.env`, starts the container. | +| `.env.example` | Template — copied to `.env` on first run for you to fill in. | +| `SHA256SUMS` | Integrity check for the image tarball. | +| `VERSION` | Plain-text version marker used by `install.sh` and `docker-compose.yml`. | +| `README.md` | This file. | + +## Prerequisites (on the remote host) + +- Docker 20.10+ with the daemon running. +- Docker Compose — either the modern `docker compose` plugin (v2) or the + legacy `docker-compose` binary. `install.sh` auto-detects. +- Whichever user runs `install.sh` needs permission to talk to the Docker + daemon (member of the `docker` group, or run under `sudo`). +- Outbound network access from the host to: + - The main wbxStoreProvision bot (`WS_URL`). + - Store Info Web (the internal API the agent proxies for). + +## Install / start + +```bash +unzip wbxprov-remote-agent-.zip +cd wbxprov-remote-agent- +./install.sh +``` + +On the first run `install.sh` will: + +1. Verify the SHA-256 of the image tarball against `SHA256SUMS`. +2. Load the image into Docker (a fast no-op on subsequent runs). +3. Copy `.env.example` → `.env` and stop, asking you to fill it in. + +Fill in `.env`: + +```bash +vi .env # set WS_URL and WS_TOKEN +``` + +Then re-run: + +```bash +./install.sh +``` + +That last run will start the container (`docker compose up -d`) and print +the log-tail command. + +## Day-to-day operations + +```bash +docker compose logs -f # tail the agent logs +docker compose ps # show container status +docker compose restart # cycle it +docker compose down # stop and remove the container +docker compose up -d # bring it back up +``` + +Healthy startup looks like: + +``` +Connecting to wss://.../ws... +Remote Agent connected to wbxStoreProvision +``` + +## Upgrading + +When you receive a newer ZIP: + +```bash +# Optional: back up your existing config +cp -a /.env ./wbxprov-remote-agent--env.bak + +# Stop the old container +cd && docker compose down && cd .. + +# Extract and start the new one +unzip wbxprov-remote-agent-.zip +cp /.env wbxprov-remote-agent-/.env +cd wbxprov-remote-agent- +./install.sh +``` + +The old image stays in Docker's local cache until you `docker image prune` +it — handy if you need to roll back quickly. + +## Coexistence with the netanalyzer agent + +This bundle uses distinct image and container names +(`wbxprov-remote-agent`), so it can run on the same host as +`sha-remote-agent` (netanalyzer's agent) without any conflict. Keep the +two deploy folders separate — each has its own `.env` pointing at its own +server. + +## Troubleshooting + +- **"Cannot talk to the Docker daemon"** — either Docker isn't running or + your user isn't in the `docker` group. Try `sudo ./install.sh` or add + yourself to the group: `sudo usermod -aG docker $USER` and log back in. +- **"Checksum verification FAILED"** — the ZIP was corrupted in transit. + Re-transfer. +- **"exec /sbin/tini: exec format error"** or **"Image architecture + does not match this host"** — the ZIP was built for the wrong CPU + architecture (typically an Apple Silicon Mac produced an `arm64` image + for an `x86_64` Linux host). `install.sh` catches this and prints the + exact rebuild command; ask your build operator to run: + ``` + ./docker/remote-agent/package.sh --platform linux/amd64 + ``` + (or `linux/arm64` if this host is ARM — run `uname -m` to check: + `x86_64` → `linux/amd64`, `aarch64` → `linux/arm64`.) + + Note that `install.sh` **always** re-runs `docker load` on the bundled + tarball, so a stale image left from an earlier wrong-arch attempt at the + same version tag will be transparently replaced when you install a + corrected bundle — no need to `docker rmi` by hand. +- **Agent connects, then disconnects immediately** — `WS_TOKEN` doesn't + match the bot's `WS_TOKEN`. Fix in `.env`, then `docker compose restart`. +- **Agent never connects** — check `WS_URL` (correct hostname, correct + scheme `ws://` vs `wss://`) and that there's no firewall between this + host and the bot. +- **Requests to SIW fail from the agent's logs** — the container needs + direct network reachability to SIW. If SIW lives on the host's local + network and the container can't reach it, uncomment `network_mode: host` + in `docker-compose.yml` (Linux only) or attach the container to the + right user-defined network. diff --git a/docker/remote-agent/deploy/docker-compose.yml b/docker/remote-agent/deploy/docker-compose.yml new file mode 100644 index 0000000..c8cd2f4 --- /dev/null +++ b/docker/remote-agent/deploy/docker-compose.yml @@ -0,0 +1,26 @@ +# Runtime-only compose file that ships inside the deploy ZIP. +# Unlike the build-time compose one level up, this one does NOT build +# anything — it references the image loaded from the tarball +# (`wbxprov-remote-agent:__VERSION__`, replaced at package time). +# +# Run: +# ./install.sh # first-time setup (loads image, seeds .env, starts) +# docker compose up -d # subsequent starts once installed +# docker compose logs -f # tail logs +# docker compose down # stop + +services: + remote-agent: + image: wbxprov-remote-agent:__VERSION__ + container_name: wbxprov-remote-agent + restart: unless-stopped + env_file: + - .env + # The agent is a websocket CLIENT — no ports to publish. + stop_signal: SIGTERM + stop_grace_period: 10s + logging: + driver: json-file + options: + max-size: '10m' + max-file: '3' diff --git a/docker/remote-agent/deploy/install.sh b/docker/remote-agent/deploy/install.sh new file mode 100755 index 0000000..1ce171f --- /dev/null +++ b/docker/remote-agent/deploy/install.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash +# +# wbxStoreProvision Remote Agent — install / (re)start on a remote host. +# +# Run this after extracting the deploy ZIP: +# unzip wbxprov-remote-agent-.zip +# cd wbxprov-remote-agent- +# ./install.sh +# +# On first run: verifies the image tarball, loads it into Docker, and drops +# a starter .env so you can fill in WS_URL / WS_TOKEN. Re-runs are safe — +# the script is idempotent. + +set -euo pipefail + +# Move to the script's own directory so relative paths work regardless of +# where the user invoked it from. +cd "$(dirname "$0")" + +RED=$'\033[0;31m' +GRN=$'\033[0;32m' +YLW=$'\033[1;33m' +RST=$'\033[0m' + +log() { printf '%s[install]%s %s\n' "$GRN" "$RST" "$*"; } +warn() { printf '%s[install]%s %s\n' "$YLW" "$RST" "$*"; } +die() { printf '%s[install]%s %s\n' "$RED" "$RST" "$*" >&2; exit 1; } + +# --- 1. Preflight ---------------------------------------------------------- + +command -v docker >/dev/null 2>&1 || die "Docker not found on PATH." +docker info >/dev/null 2>&1 \ + || die "Cannot talk to the Docker daemon. Is it running / do you have permission?" + +# Detect either `docker compose` (v2 plugin) or the legacy `docker-compose`. +if docker compose version >/dev/null 2>&1; then + COMPOSE=(docker compose) +elif command -v docker-compose >/dev/null 2>&1; then + COMPOSE=(docker-compose) +else + die "Neither 'docker compose' nor 'docker-compose' is available. Install Docker Compose." +fi + +[[ -f VERSION ]] || die "VERSION file missing from bundle — is this a valid deploy ZIP?" +VERSION="$(cat VERSION)" + +IMAGE_TARBALL="wbxprov-remote-agent-${VERSION}.tar.gz" +[[ -f "$IMAGE_TARBALL" ]] || die "Image tarball not found: $IMAGE_TARBALL" + +# --- 2. Verify checksum (optional; skip gracefully if no shasum tool) ----- + +if [[ -f SHA256SUMS ]]; then + if command -v sha256sum >/dev/null 2>&1; then + log "Verifying SHA256 checksum..." + sha256sum -c SHA256SUMS >/dev/null || die "Checksum verification FAILED." + elif command -v shasum >/dev/null 2>&1; then + log "Verifying SHA256 checksum (macOS shasum)..." + shasum -a 256 -c SHA256SUMS >/dev/null || die "Checksum verification FAILED." + else + warn "No sha256sum/shasum tool found — skipping integrity check." + fi + log "Checksum OK." +else + warn "No SHA256SUMS file in bundle — skipping integrity check." +fi + +# --- 3. Load the image ----------------------------------------------------- +# ALWAYS docker load, unconditionally. `docker load` reassigns the tag to +# whatever's in the tarball and is a fast no-op when the layers are already +# present, so this is safe to re-run. We intentionally do NOT "skip if the +# tag already exists" — a stale image left over from a previous wrong-arch +# attempt has this exact tag, and skipping the load would hide the correct +# image in the tarball we're actually holding. + +IMAGE_TAG="wbxprov-remote-agent:${VERSION}" + +log "Loading Docker image from ${IMAGE_TARBALL}..." +docker load -i "$IMAGE_TARBALL" + +# --- 3a. Platform sanity check -------------------------------------------- +# Inspect the image we just (re)loaded — this is the ground truth for what +# was actually shipped in this ZIP, independent of anything that was on the +# host before. If the tarball was built for a different CPU architecture +# than this host, Docker will let it "run" but tini (and node) fail with +# cryptic errors like "exec format error". Catch that up front with a +# clear message. + +IMAGE_ARCH="$(docker image inspect --format '{{.Architecture}}' "$IMAGE_TAG" 2>/dev/null || true)" +IMAGE_ID_SHORT="$(docker image inspect --format '{{.Id}}' "$IMAGE_TAG" 2>/dev/null | sed 's|^sha256:||' | cut -c1-12)" + +HOST_ARCH_RAW="$(uname -m)" +case "$HOST_ARCH_RAW" in + x86_64|amd64) HOST_ARCH="amd64" ;; + aarch64|arm64) HOST_ARCH="arm64" ;; + armv7l) HOST_ARCH="arm" ;; + *) HOST_ARCH="$HOST_ARCH_RAW" ;; +esac + +log "Loaded ${IMAGE_TAG} (id: ${IMAGE_ID_SHORT:-unknown}, arch: ${IMAGE_ARCH:-unknown}); host arch: ${HOST_ARCH}." + +if [[ -z "$IMAGE_ARCH" ]]; then + die "Could not read image architecture from Docker — is the image really loaded?" +fi + +if [[ "$IMAGE_ARCH" != "$HOST_ARCH" ]]; then + warn "Image architecture (${IMAGE_ARCH}) does not match this host (${HOST_ARCH})." + warn "The container would fail to start with 'exec /sbin/tini: exec format error'." + warn "" + warn "This means the ZIP was built for the wrong CPU. On the build host:" + warn " 1. git pull # make sure you have the fixed package.sh" + warn " 2. ./docker/remote-agent/package.sh --platform linux/${HOST_ARCH}" + warn "The updated package.sh verifies the architecture during build and" + warn "refuses to produce a ZIP that would fail this check." + die "Aborting install. Ship a linux/${HOST_ARCH} bundle and re-run this script." +fi + +# --- 4. Bootstrap .env ----------------------------------------------------- + +if [[ ! -f .env ]]; then + if [[ -f .env.example ]]; then + cp .env.example .env + warn ".env did not exist — copied .env.example into place." + warn "EDIT .env now to set WS_URL and WS_TOKEN, then re-run this script." + exit 0 + else + die ".env is missing and no .env.example is bundled. Cannot proceed." + fi +fi + +# --- 5. Start the container ----------------------------------------------- + +log "Starting wbxprov-remote-agent (version ${VERSION})..." +"${COMPOSE[@]}" up -d + +log "Done. Tail logs with:" +log " ${COMPOSE[*]} logs -f" +log "Stop with:" +log " ${COMPOSE[*]} down" diff --git a/docker/remote-agent/docker-compose.yml b/docker/remote-agent/docker-compose.yml new file mode 100644 index 0000000..634b8c8 --- /dev/null +++ b/docker/remote-agent/docker-compose.yml @@ -0,0 +1,40 @@ +# Build-time compose file for the wbxStoreProvision remote agent. +# This one BUILDS from source; the runtime-only version used inside the +# deploy ZIP lives at deploy/docker-compose.yml. +# +# docker compose -f docker/remote-agent/docker-compose.yml up -d --build +# +# Environment values come from docker/remote-agent/.env (copy the .env.example +# next to it). Set WS_URL to the main wbxStoreProvision bot's public +# websocket endpoint, and WS_TOKEN to the shared secret configured on the +# bot side. + +services: + remote-agent: + build: + context: . + dockerfile: Dockerfile + image: wbxprov-remote-agent:latest + container_name: wbxprov-remote-agent + restart: unless-stopped + env_file: + - .env + # The agent is a websocket CLIENT — nothing to publish. It just + # needs outbound network access to: + # - the main wbxStoreProvision bot (WS_URL) + # - Store Info Web (whatever internal SIW endpoint it proxies) + # + # If those live on the host's Docker network, uncomment + # `network_mode: host` (Linux only) or attach to a shared + # user-defined network. + # + # network_mode: host + + stop_signal: SIGTERM + stop_grace_period: 10s + + logging: + driver: json-file + options: + max-size: '10m' + max-file: '3' diff --git a/docker/remote-agent/inspect-bundle.sh b/docker/remote-agent/inspect-bundle.sh new file mode 100755 index 0000000..d5b3d7f --- /dev/null +++ b/docker/remote-agent/inspect-bundle.sh @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +# +# Inspect a wbxprov-remote-agent deploy ZIP (or the tarball inside one) and +# report the actual OS/architecture of the Docker image it contains — WITHOUT +# needing docker installed. Reads the OCI/Docker image manifest directly out +# of the tarball. +# +# Use this before shipping a ZIP to a remote host to confirm you built the +# right platform. The main `package.sh` already runs `docker image inspect` +# on the image it just built, but this script gives you a completely +# independent check (no docker daemon involved at all) that also works on +# machines that never had docker on them. +# +# Usage: +# ./docker/remote-agent/inspect-bundle.sh +# ./docker/remote-agent/inspect-bundle.sh # auto-detect newest ZIP in dist/ +# +# Exit codes: +# 0 bundle looks well-formed; arch/os printed +# 1 bad arguments / no bundle found +# 2 bundle is malformed or arch could not be read +# +# Optional env: +# EXPECTED_ARCH=amd64 die if the image's architecture does not match +# EXPECTED_OS=linux die if the image's OS does not match + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +DIST_DIR="$SCRIPT_DIR/dist" + +RED=$'\033[0;31m' +GRN=$'\033[0;32m' +YLW=$'\033[1;33m' +RST=$'\033[0m' + +log() { printf '%s[inspect]%s %s\n' "$GRN" "$RST" "$*"; } +warn() { printf '%s[inspect]%s %s\n' "$YLW" "$RST" "$*"; } +die() { printf '%s[inspect]%s %s\n' "$RED" "$RST" "$*" >&2; exit 2; } + +command -v python3 >/dev/null 2>&1 || die "python3 is required (ships with macOS; on Linux: 'apt install python3')." + +BUNDLE="${1:-}" +if [[ -z "$BUNDLE" ]]; then + # Auto-detect: newest ZIP in dist/ + [[ -d "$DIST_DIR" ]] || { printf '%s\n' "usage: $0 "; exit 1; } + BUNDLE="$(ls -t "$DIST_DIR"/*.zip 2>/dev/null | head -n 1 || true)" + [[ -n "$BUNDLE" ]] || { printf '%s\n' "usage: $0 (no ZIPs in $DIST_DIR)"; exit 1; } + log "Auto-detected newest bundle: $BUNDLE" +fi + +[[ -e "$BUNDLE" ]] || die "File not found: $BUNDLE" + +# Resolve to the actual image tarball. If given a ZIP, extract to a tempdir +# and locate the tar.gz inside; otherwise assume the arg IS the tarball. +TMPDIR_INSPECT="" +cleanup() { [[ -n "$TMPDIR_INSPECT" ]] && rm -rf "$TMPDIR_INSPECT"; } +trap cleanup EXIT + +case "$BUNDLE" in + *.zip) + command -v unzip >/dev/null 2>&1 || die "unzip is required to inspect a ZIP." + TMPDIR_INSPECT="$(mktemp -d)" + log "Extracting ZIP into temp dir for inspection..." + unzip -q "$BUNDLE" -d "$TMPDIR_INSPECT" + TARBALL="$(find "$TMPDIR_INSPECT" -maxdepth 3 -name '*.tar.gz' -type f | head -n 1 || true)" + [[ -n "$TARBALL" ]] || die "Could not find an image tarball (*.tar.gz) inside the ZIP." + ;; + *.tar.gz|*.tgz|*.tar) + TARBALL="$BUNDLE" + ;; + *) + die "Unrecognized bundle type: $BUNDLE (expected .zip, .tar.gz, .tgz, or .tar)" + ;; +esac + +log "Reading image manifest from: $(basename "$TARBALL")" + +# The image tarball is a standard docker/OCI save. It contains: +# manifest.json -> lists image config path (per-tag entry) +# .json OR blobs/sha256/ -> per-image config JSON +# We read manifest.json to find the config blob, then read the config +# blob's 'architecture' and 'os' fields. Everything happens in-memory via +# `tar -xO`, so nothing is written to disk. + +DECOMPRESS="cat" +case "$TARBALL" in + *.gz|*.tgz) DECOMPRESS="gunzip -c" ;; +esac + +MANIFEST_JSON="$($DECOMPRESS "$TARBALL" | tar -xO manifest.json 2>/dev/null || true)" +[[ -n "$MANIFEST_JSON" ]] || die "No manifest.json in tarball — is this really a 'docker save' bundle?" + +CONFIG_PATH="$(printf '%s' "$MANIFEST_JSON" | python3 -c " +import json, sys +data = json.load(sys.stdin) +if not data: + sys.exit('empty manifest') +entry = data[0] +config = entry.get('Config') or entry.get('config') +if not config: + sys.exit('no Config in manifest entry') +print(config) +")" + +CONFIG_JSON="$($DECOMPRESS "$TARBALL" | tar -xO "$CONFIG_PATH" 2>/dev/null || true)" +[[ -n "$CONFIG_JSON" ]] || die "Could not read config blob '$CONFIG_PATH' from tarball." + +read -r ARCH OS <<<"$(printf '%s' "$CONFIG_JSON" | python3 -c " +import json, sys +d = json.load(sys.stdin) +print(d.get('architecture','?'), d.get('os','?')) +")" + +log "Image tags: $(printf '%s' "$MANIFEST_JSON" | python3 -c "import json,sys; d=json.load(sys.stdin); print(', '.join(d[0].get('RepoTags') or ['(none)']))")" +log "Image OS: ${OS}" +log "Image arch: ${ARCH}" + +FAIL=0 + +if [[ -n "${EXPECTED_ARCH:-}" && "${ARCH}" != "${EXPECTED_ARCH}" ]]; then + warn "Expected arch '${EXPECTED_ARCH}' but got '${ARCH}'." + FAIL=1 +fi + +if [[ -n "${EXPECTED_OS:-}" && "${OS}" != "${EXPECTED_OS}" ]]; then + warn "Expected OS '${EXPECTED_OS}' but got '${OS}'." + FAIL=1 +fi + +if (( FAIL != 0 )); then + die "Bundle does not match expected OS/arch. Rebuild with the correct --platform." +fi + +log "OK — bundle looks well-formed." diff --git a/docker/remote-agent/package.json b/docker/remote-agent/package.json new file mode 100644 index 0000000..f88a18e --- /dev/null +++ b/docker/remote-agent/package.json @@ -0,0 +1,19 @@ +{ + "name": "wbxprov-remote-agent", + "version": "1.1.0", + "private": true, + "description": "Standalone container for the wbxStoreProvision remote agent (WebSocket proxy for Store Info Web from an internal network).", + "main": "remoteAgent.js", + "type": "commonjs", + "scripts": { + "start": "node remoteAgent.js" + }, + "engines": { + "node": ">=18" + }, + "dependencies": { + "axios": "^1.16.1", + "dotenv": "^17.4.2", + "ws": "^8.20.1" + } +} diff --git a/docker/remote-agent/package.sh b/docker/remote-agent/package.sh new file mode 100755 index 0000000..f2303ca --- /dev/null +++ b/docker/remote-agent/package.sh @@ -0,0 +1,334 @@ +#!/usr/bin/env bash +# +# Package the wbxStoreProvision remote agent into a self-contained ZIP +# for offline / manual transfer to a remote Docker host. +# +# What this script does: +# 1. Reads the version from docker/remote-agent/package.json. +# 2. Builds `wbxprov-remote-agent:` from the local source tree. +# 3. `docker save`s the image, gzip-compressed, into a temp staging dir. +# 4. Copies deploy/docker-compose.yml, deploy/install.sh, deploy/README.md, +# and .env.example into the staging dir. Rewrites the compose file's +# __VERSION__ placeholder to match the built image tag. +# 5. Writes VERSION and SHA256SUMS files for identification / integrity. +# 6. Zips the whole staging dir into docker/remote-agent/dist/. +# +# Usage: +# ./docker/remote-agent/package.sh # tag=package.json, platform=linux/amd64 +# ./docker/remote-agent/package.sh --tag 1.0.1 # override tag +# ./docker/remote-agent/package.sh --platform linux/arm64 # ARM Linux target +# ./docker/remote-agent/package.sh --platform linux/amd64 # explicit default (Linux RH/Rocky/CentOS/Ubuntu on Intel) +# +# The image is ALWAYS built for the target platform via `docker buildx +# build --platform ...` so the tarball you ship matches the remote host. +# Default is linux/amd64 because that's the overwhelmingly common Linux +# server architecture; override with --platform if your remote host is +# something else (e.g. linux/arm64 for a Raspberry Pi or ARM-based server). +# +# Requires: docker (with buildx), zip, node (for reading package.json), +# sha256sum OR shasum (macOS ships shasum by default). + +set -euo pipefail + +# --- Locations -------------------------------------------------------------- + +# The build context is this directory (docker/remote-agent), which contains +# both the Dockerfile and the single agent source file. This is intentionally +# self-contained — the agent doesn't need any of the bot's source. +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +CONTEXT_DIR="$SCRIPT_DIR" +DIST_DIR="$SCRIPT_DIR/dist" +DEPLOY_DIR="$SCRIPT_DIR/deploy" +DOCKERFILE="$SCRIPT_DIR/Dockerfile" + +# --- Colors ----------------------------------------------------------------- + +GRN=$'\033[0;32m' +YLW=$'\033[1;33m' +RED=$'\033[0;31m' +RST=$'\033[0m' + +log() { printf '%s[package]%s %s\n' "$GRN" "$RST" "$*"; } +warn() { printf '%s[package]%s %s\n' "$YLW" "$RST" "$*"; } +die() { printf '%s[package]%s %s\n' "$RED" "$RST" "$*" >&2; exit 1; } + +# --- Argument parsing ------------------------------------------------------- + +VERSION="" +# Default target platform. Overwhelming majority of Linux server hosts +# (RHEL, Rocky, CentOS, Ubuntu, Debian) run on x86_64. Override with +# --platform for ARM Linux (linux/arm64) or anything else. +PLATFORM="linux/amd64" +CHECK_ONLY=0 + +while [[ $# -gt 0 ]]; do + case "$1" in + --tag) + shift + VERSION="${1:-}" + shift || true + ;; + --platform) + shift + PLATFORM="${1:-}" + shift || true + ;; + --check) + # Preflight only: verify docker/buildx/binfmt/builder are set up + # for the requested --platform. Do not build anything. + CHECK_ONLY=1 + shift + ;; + -h|--help) + grep '^#' "$0" | sed 's/^# \{0,1\}//' + exit 0 + ;; + *) + die "Unknown argument: $1 (try --help)" + ;; + esac +done + +[[ -n "$PLATFORM" ]] || die "--platform requires a value (e.g. linux/amd64, linux/arm64)" + +# --- Preflight -------------------------------------------------------------- + +command -v docker >/dev/null 2>&1 || die "docker not found on PATH." +command -v zip >/dev/null 2>&1 || die "zip not found on PATH." +command -v node >/dev/null 2>&1 || die "node not found on PATH." + +# buildx is required so we can cross-build for a specific target platform +# on any host (e.g. build linux/amd64 from an Apple Silicon Mac). +docker buildx version >/dev/null 2>&1 \ + || die "docker buildx not available. Install Docker Desktop or the buildx plugin." + +if [[ -z "$VERSION" ]]; then + VERSION="$(node -p "require('$SCRIPT_DIR/package.json').version")" +fi +[[ -n "$VERSION" ]] || die "Could not determine version." + +log "Packaging wbxprov-remote-agent version: ${VERSION}" +log "Target platform: ${PLATFORM}" + +IMAGE_TAG="wbxprov-remote-agent:${VERSION}" +BUNDLE_NAME="wbxprov-remote-agent-${VERSION}" +STAGING_DIR="$(mktemp -d)" +STAGING_ROOT="$STAGING_DIR/$BUNDLE_NAME" +mkdir -p "$STAGING_ROOT" + +# Guarantee cleanup even on error. +cleanup() { rm -rf "$STAGING_DIR"; } +trap cleanup EXIT + +# Normalize host arch into a linux/* platform string for cross-build detection. +HOST_ARCH_RAW="$(uname -m)" +case "$HOST_ARCH_RAW" in + x86_64|amd64) HOST_LINUX_PLATFORM="linux/amd64" ;; + aarch64|arm64) HOST_LINUX_PLATFORM="linux/arm64" ;; + armv7l) HOST_LINUX_PLATFORM="linux/arm/v7" ;; + *) HOST_LINUX_PLATFORM="linux/${HOST_ARCH_RAW}" ;; +esac + +EXPECTED_ARCH="${PLATFORM##*/}" + +# --- 1. Ensure a cross-arch-capable buildx builder -------------------------- +# The DEFAULT buildx builder on Docker Desktop uses the "docker" driver, which +# is tied to the daemon's native platform. Passing --platform linux/amd64 on +# an arm64 host with that driver can silently produce an arm64 image (which +# is exactly the "image arch does not match host" failure the install.sh +# sanity check catches on the target machine). +# +# We work around it by creating (once) a dedicated builder with the +# "docker-container" driver, which spins up an isolated BuildKit instance +# capable of cross-arch builds when QEMU/binfmt is available. + +BUILDER_NAME="wbxprov-remote-agent-builder" +CURRENT_BUILDER_DRIVER="" +if docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then + CURRENT_BUILDER_DRIVER="$(docker buildx inspect "$BUILDER_NAME" 2>/dev/null | awk -F': *' '/^Driver:/ {print $2; exit}')" +fi + +if [[ -z "$CURRENT_BUILDER_DRIVER" ]]; then + log "Creating dedicated buildx builder '${BUILDER_NAME}' (docker-container driver)..." + docker buildx create \ + --name "$BUILDER_NAME" \ + --driver docker-container \ + --bootstrap >/dev/null +elif [[ "$CURRENT_BUILDER_DRIVER" != "docker-container" ]]; then + # A builder with this exact name exists but uses the wrong driver — the + # plain `docker` driver, most likely — which is the exact silent-fail + # source: it's pinned to the daemon's native arch and will happily ignore + # --platform. Recreate it correctly. + warn "Existing builder '${BUILDER_NAME}' uses driver '${CURRENT_BUILDER_DRIVER}', not 'docker-container'." + warn "Recreating it so cross-arch builds actually respect --platform..." + docker buildx rm "$BUILDER_NAME" >/dev/null 2>&1 || true + docker buildx create \ + --name "$BUILDER_NAME" \ + --driver docker-container \ + --bootstrap >/dev/null +else + # Right builder, right driver — just make sure it's up. + docker buildx inspect --bootstrap "$BUILDER_NAME" >/dev/null +fi + +# --- 2. Cross-arch binfmt (only when needed) -------------------------------- +# Docker Desktop ships QEMU/binfmt handlers by default so this usually no-ops, +# but plain Docker Engine, Colima, or rootless setups often don't. When we're +# cross-building, best-effort install binfmt for the target arch. If it fails +# (e.g. no --privileged, no internet, no image), warn but continue — the +# subsequent build step will fail fast with a clearer error if binfmt truly +# is missing. + +if [[ "$PLATFORM" != "$HOST_LINUX_PLATFORM" ]]; then + log "Cross-arch build (${HOST_LINUX_PLATFORM} -> ${PLATFORM}); ensuring binfmt handlers..." + if ! docker run --privileged --rm tonistiigi/binfmt --install "$EXPECTED_ARCH" >/dev/null 2>&1; then + warn "Could not auto-install binfmt for ${EXPECTED_ARCH}. If the build fails, install it manually:" + warn " docker run --privileged --rm tonistiigi/binfmt --install all" + fi +fi + +# --- 2a. --check preflight short-circuit ------------------------------------ +# If --check was passed, we've now verified: docker daemon reachable, buildx +# available, a docker-container builder exists (or was just recreated) for +# cross-arch, and binfmt handlers were attempted. Report and exit without +# building anything. + +if (( CHECK_ONLY == 1 )); then + log "" + log "==========================================================" + log " Preflight OK for target platform: ${PLATFORM}" + log " host platform: ${HOST_LINUX_PLATFORM}" + log " builder: ${BUILDER_NAME} (docker-container)" + if [[ "$PLATFORM" != "$HOST_LINUX_PLATFORM" ]]; then + log " cross-arch: yes (binfmt registered above)" + else + log " cross-arch: no (native build)" + fi + log "==========================================================" + log "Re-run without --check to actually produce a bundle." + exit 0 +fi + +# --- 3. Build directly to a portable tarball -------------------------------- +# `--output type=docker,dest=...` writes a `docker load`-compatible tarball +# straight to disk. This intentionally bypasses `--load` (and therefore the +# question of whether the local daemon can even store cross-arch images). + +UNZIPPED_TAR="$STAGING_ROOT/${BUNDLE_NAME}.tar" +log "Building ${IMAGE_TAG} for ${PLATFORM} -> $(basename "$UNZIPPED_TAR") (context = ${CONTEXT_DIR})..." +docker buildx build \ + --builder "$BUILDER_NAME" \ + --platform "$PLATFORM" \ + --output "type=docker,dest=${UNZIPPED_TAR},name=${IMAGE_TAG}" \ + -f "$DOCKERFILE" \ + "$CONTEXT_DIR" + +[[ -s "$UNZIPPED_TAR" ]] || die "buildx produced no output tarball. Aborting." + +# --- 4. Verify the built image actually matches --platform ------------------ +# Regression guard: if buildx (or binfmt) silently ignored the requested +# platform, catch it here instead of shipping a broken bundle that only +# fails on the remote host with an "exec format error". + +log "Verifying built image architecture..." +docker load -i "$UNZIPPED_TAR" >/dev/null +ACTUAL_ARCH="$(docker image inspect --format '{{.Architecture}}' "$IMAGE_TAG")" +if [[ "$ACTUAL_ARCH" != "$EXPECTED_ARCH" ]]; then + die "Built image architecture is '${ACTUAL_ARCH}' but '${EXPECTED_ARCH}' was requested. + This usually means buildx couldn't cross-compile for ${PLATFORM}. + Try installing binfmt handlers explicitly: + docker run --privileged --rm tonistiigi/binfmt --install all + Then re-run: + $0 --platform ${PLATFORM}" +fi +log "Verified: image architecture is ${ACTUAL_ARCH} (matches requested ${EXPECTED_ARCH})." + +# Also tag :latest locally for convenience (only when it matches the host, +# so we don't leave a broken cross-arch :latest sitting in the daemon). +if [[ "$PLATFORM" == "$HOST_LINUX_PLATFORM" ]]; then + docker tag "$IMAGE_TAG" "wbxprov-remote-agent:latest" 2>/dev/null || true +fi + +# --- 5. Compress the tarball ------------------------------------------------ + +IMAGE_TARBALL="${BUNDLE_NAME}.tar.gz" +log "Compressing image tarball -> ${IMAGE_TARBALL}..." +gzip -c "$UNZIPPED_TAR" > "$STAGING_ROOT/$IMAGE_TARBALL" +rm -f "$UNZIPPED_TAR" + +TAR_SIZE_MB="$(du -m "$STAGING_ROOT/$IMAGE_TARBALL" | cut -f1)" +log "Image tarball size: ${TAR_SIZE_MB} MB" + +# --- 6. Copy deploy assets -------------------------------------------------- + +log "Copying deploy assets into bundle..." +cp "$SCRIPT_DIR/.env.example" "$STAGING_ROOT/.env.example" +cp "$DEPLOY_DIR/install.sh" "$STAGING_ROOT/install.sh" +cp "$DEPLOY_DIR/README.md" "$STAGING_ROOT/README.md" + +# Template the version into the runtime compose file so it references the +# specific image tag we just built. +sed "s|__VERSION__|${VERSION}|g" \ + "$DEPLOY_DIR/docker-compose.yml" > "$STAGING_ROOT/docker-compose.yml" + +chmod +x "$STAGING_ROOT/install.sh" + +# --- 7. VERSION + SHA256SUMS ----------------------------------------------- + +printf '%s\n' "$VERSION" > "$STAGING_ROOT/VERSION" + +log "Computing SHA-256 checksum for the image tarball..." +pushd "$STAGING_ROOT" >/dev/null +if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$IMAGE_TARBALL" > SHA256SUMS +elif command -v shasum >/dev/null 2>&1; then + # macOS: shasum -a 256 emits the same " " format + # `sha256sum -c` understands. + shasum -a 256 "$IMAGE_TARBALL" > SHA256SUMS +else + warn "No sha256sum/shasum available — skipping checksum file." +fi +popd >/dev/null + +# --- 8. Zip ----------------------------------------------------------------- + +mkdir -p "$DIST_DIR" +ZIP_PATH="$DIST_DIR/${BUNDLE_NAME}.zip" +rm -f "$ZIP_PATH" + +log "Creating ZIP: ${ZIP_PATH}" +# Zip from inside the temp dir so the archive contains the top-level folder +# with the bundle name (matching what install.sh expects when unzipped). +(cd "$STAGING_DIR" && zip -qr "$ZIP_PATH" "$BUNDLE_NAME") + +ZIP_SIZE_MB="$(du -m "$ZIP_PATH" | cut -f1)" + +# --- 9. Independent post-build inspection ---------------------------------- +# Final belt-and-suspenders: run inspect-bundle.sh against the ZIP we just +# produced. This reads the image config straight out of the tarball WITHOUT +# going through the docker daemon, so it catches anything a misbehaving +# daemon or `docker image inspect` might have hidden earlier. + +INSPECT_SCRIPT="$SCRIPT_DIR/inspect-bundle.sh" +if [[ -x "$INSPECT_SCRIPT" ]]; then + log "Running independent (no-docker) inspection on the final ZIP..." + EXPECTED_OS=linux EXPECTED_ARCH="$EXPECTED_ARCH" \ + "$INSPECT_SCRIPT" "$ZIP_PATH" \ + || die "Independent inspection FAILED. Bundle at $ZIP_PATH is not fit to ship." +else + warn "inspect-bundle.sh not found or not executable; skipping independent verification." +fi + +# --- 10. Done --------------------------------------------------------------- + +log "" +log "==========================================================" +log " Bundle ready:" +log " $ZIP_PATH" +log " (${ZIP_SIZE_MB} MB, built for ${PLATFORM})" +log "==========================================================" +log "" +log "Transfer to the remote host, then:" +log " unzip ${BUNDLE_NAME}.zip" +log " cd ${BUNDLE_NAME}" +log " ./install.sh" diff --git a/docker/remote-agent/remoteAgent.js b/docker/remote-agent/remoteAgent.js new file mode 100644 index 0000000..2e8f7ef --- /dev/null +++ b/docker/remote-agent/remoteAgent.js @@ -0,0 +1,129 @@ +const WebSocket = require('ws'); +const axios = require('axios'); +const https = require('https'); +require('dotenv').config(); + +const WS_URL = process.env.WS_URL; +const WS_TOKEN = process.env.WS_TOKEN; + +if (!WS_URL) { + console.error('WS_URL is not set in .env'); + process.exit(1); +} + +const INITIAL_BACKOFF_MS = 2000; +const MAX_BACKOFF_MS = 60000; +const PROXY_TIMEOUT_MS = 30000; + +// Shared https.Agent used only when the bot flags a proxied request with +// `insecure: true` (e.g. reaching Store Info Web, which is served with an +// internal-CA cert Node doesn't know about). All other requests use axios's +// default (validated) TLS. Kept as a module-level singleton so we don't +// leak sockets per request. +const insecureHttpsAgent = new https.Agent({ rejectUnauthorized: false }); + +let ws = null; +let reconnectAttempts = 0; +let shuttingDown = false; + +/** + * If WS_TOKEN is provided, send it as an Authorization: Bearer header so the + * secret stays out of access logs. (The server still accepts the legacy + * ?token=... query parameter for backward compatibility.) + */ +function buildClientOptions() { + if (!WS_TOKEN) return undefined; + return { headers: { Authorization: `Bearer ${WS_TOKEN}` } }; +} + +function connect() { + console.log(`Connecting to ${WS_URL}...`); + + ws = new WebSocket(WS_URL, buildClientOptions()); + + ws.on('open', () => { + console.log('Remote Agent connected to wbxStoreProvision'); + reconnectAttempts = 0; + }); + + ws.on('message', async (data) => { + let request; + try { + request = JSON.parse(data); + if (request.action !== 'proxyRequest') return; + + const insecure = request.insecure === true; + console.log( + `Proxying ${request.method || 'GET'} ${request.url}${insecure ? ' (insecure TLS)' : ''}`, + ); + + const response = await axios({ + method: request.method || 'GET', + url: request.url, + headers: request.headers || {}, + auth: request.auth || undefined, + data: request.body || undefined, + timeout: PROXY_TIMEOUT_MS, + ...(insecure ? { httpsAgent: insecureHttpsAgent } : {}), + }); + + ws.send( + JSON.stringify({ + requestId: request.requestId, + status: response.status, + data: response.data, + headers: response.headers, + }), + ); + } catch (err) { + console.error('Proxy error:', err.message); + ws.send( + JSON.stringify({ + requestId: request ? request.requestId : null, + error: err.message, + status: err.response?.status || 500, + data: err.response?.data || null, + }), + ); + } + }); + + ws.on('close', (code) => { + console.log(`Disconnected (code: ${code}).`); + if (!shuttingDown) scheduleReconnect(); + }); + + ws.on('error', (err) => { + console.error('WebSocket error:', err.message); + }); +} + +function scheduleReconnect() { + reconnectAttempts++; + const backoff = Math.min( + INITIAL_BACKOFF_MS * Math.pow(1.5, reconnectAttempts - 1), + MAX_BACKOFF_MS, + ); + console.log( + `Reconnecting in ${Math.round(backoff / 1000)}s... (attempt ${reconnectAttempts})`, + ); + setTimeout(connect, backoff); +} + +connect(); + +function shutdownRemote(signal) { + console.log(`${signal} received. Shutting down remote agent...`); + shuttingDown = true; + if (ws) { + try { + ws.close(); + } catch (_e) { + // ignore close errors during shutdown + } + } + process.exit(0); +} + +process.on('SIGINT', () => shutdownRemote('SIGINT')); +process.on('SIGTERM', () => shutdownRemote('SIGTERM')); diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..59fbe48 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,30 @@ +import js from '@eslint/js'; +import globals from 'globals'; +import prettier from 'eslint-config-prettier'; + +export default [ + { + ignores: ['node_modules/**', 'greetings/**', 'buildingFile.csv', 'locationFile.csv'], + }, + js.configs.recommended, + { + languageOptions: { + ecmaVersion: 2023, + sourceType: 'module', + globals: { + ...globals.node, + fetch: 'readonly', + FormData: 'readonly', + Blob: 'readonly', + }, + }, + rules: { + 'no-console': 'off', + 'no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], + eqeqeq: ['error', 'always'], + 'no-var': 'error', + 'prefer-const': 'warn', + }, + }, + prettier, +]; diff --git a/greetings/AEGreeting.wav b/greetings/AEGreeting.wav new file mode 100644 index 0000000..2503d63 Binary files /dev/null and b/greetings/AEGreeting.wav differ diff --git a/greetings/AerieGreeting.wav b/greetings/AerieGreeting.wav new file mode 100644 index 0000000..af390d3 Binary files /dev/null and b/greetings/AerieGreeting.wav differ diff --git a/greetings/OfflineGreeting.wav b/greetings/OfflineGreeting.wav new file mode 100644 index 0000000..9240fe0 Binary files /dev/null and b/greetings/OfflineGreeting.wav differ diff --git a/greetings/UnsubscribedGreeting.wav b/greetings/UnsubscribedGreeting.wav new file mode 100644 index 0000000..7f2c786 Binary files /dev/null and b/greetings/UnsubscribedGreeting.wav differ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..b4002ce --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11319 @@ +{ + "name": "wbxcallprov", + "version": "2.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "wbxcallprov", + "version": "2.0.0", + "license": "ISC", + "dependencies": { + "dotenv": "^16.4.5", + "node-cron": "^3.0.3", + "undici": "^6.19.8", + "webex-node-bot-framework": "^2.5.1", + "ws": "^8.20.1" + }, + "devDependencies": { + "@eslint/js": "^9.9.0", + "eslint": "^9.9.0", + "eslint-config-prettier": "^9.1.0", + "globals": "^15.9.0", + "prettier": "^3.3.3" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz", + "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz", + "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/traverse": "^7.29.7", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.29.7.tgz", + "integrity": "sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.11" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz", + "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz", + "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.29.7.tgz", + "integrity": "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-wrap-function": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz", + "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz", + "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.29.7.tgz", + "integrity": "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.7.tgz", + "integrity": "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-decorators": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-default-from": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.29.7.tgz", + "integrity": "sha512-p+G5BNXDcy3bOXplhY4HybQ1GxH3i2Tppmdm/3epyRu2VgJJZuUlZ61MqRTg582Q7ZLBdP7fePYvsumSEkMxcQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.29.7.tgz", + "integrity": "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-default-from": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.29.7.tgz", + "integrity": "sha512-foag0BB37ROhdeIX9O8G0jX7hw0UekJc04cHMrYLOnrErsnBKqJGHJ8eDRpoCFZBvEPPygmmtw4qyU97qa4oOw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.29.7.tgz", + "integrity": "sha512-ajMX6QPcyomotqwpzhkYGxcK2i/us0rs1Qo9QvUpa+Fca0FTmqrzKrctoIYLMxcOhGZldGT/BAVkRGTWBiR8gQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.7.tgz", + "integrity": "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.29.7.tgz", + "integrity": "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.29.7.tgz", + "integrity": "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.29.7.tgz", + "integrity": "sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.29.7.tgz", + "integrity": "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.29.7.tgz", + "integrity": "sha512-qV0OGGBVacduzQHE649JyCneOFI/maT+YKsO+K4Yi3xv2wTPNjM/W2o2gdzMwEAZz7fXNTHAe0NcSg30bIN69g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.29.7.tgz", + "integrity": "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.29.7.tgz", + "integrity": "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.29.7.tgz", + "integrity": "sha512-wRHeUjUjCZnMHmiO5bRgjFLcoEh7JyTdByOW11ahhwNa4V0bmeGEaIvt51yq0zQp2yWIpqfxXXPyUP6GFJZHOQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-flow": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.29.7.tgz", + "integrity": "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.29.7.tgz", + "integrity": "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz", + "integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.7.tgz", + "integrity": "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.29.7.tgz", + "integrity": "sha512-idmp1dFaekP9GbcMvG24Kvw2BfhFZjHnNJCkV4WuIY4PskJzwI3f1N5OdgYke38T7rftO6ERulFRn2cFeZwRkg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.29.7.tgz", + "integrity": "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7", + "@babel/plugin-transform-parameters": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.29.7.tgz", + "integrity": "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.29.7.tgz", + "integrity": "sha512-6GM1dhvK3gNODkXcEcMCOLEDCLSoZ/sBbro2Ax8HURyasQ4NshagQixkRFdh5niI6E4gmA/jYI/4aT7rRos3ZQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.29.7.tgz", + "integrity": "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.29.7.tgz", + "integrity": "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.29.7.tgz", + "integrity": "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.29.7.tgz", + "integrity": "sha512-+1wdDMGNb4UPeY3Q4L5yLiYe6TXPXubs4NjrgRFw13hPRLJfEMw2Q5OXkee6/IfdqePIeW4Jjwe3aBh7SdKz4Q==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.29.7.tgz", + "integrity": "sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-jsx": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.29.7.tgz", + "integrity": "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.29.7.tgz", + "integrity": "sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.7.tgz", + "integrity": "sha512-xmAscdE/AsqRW7vutbPNoUmu/nF5SrLKPs7aoJgEjo35lLKA/Bc0i2rMv/hr1+Y0o1bQCiVtith3u2vdgRL39Q==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz", + "integrity": "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/plugin-syntax-typescript": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.29.7.tgz", + "integrity": "sha512-7D/x/23/d/3VqZ0QA+LGbZMlGwZjztBygSWWWsfTPoQ1oQ6Q1P6Mr3d0kk42XabyUVw+fha3LqdRsFqeKqvCyA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/polyfill": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz", + "integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==", + "deprecated": "🚨 This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information.", + "license": "MIT", + "dependencies": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.29.7.tgz", + "integrity": "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-syntax-jsx": "^7.29.7", + "@babel/plugin-transform-modules-commonjs": "^7.29.7", + "@babel/plugin-transform-typescript": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs2": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.29.7.tgz", + "integrity": "sha512-5GidEBf/rOQlv4sUknPRgboZEvzt/je7CpbkCZ2o7ojs9JbldxdXJinGLYE0sYR9mfPpRz3Q3D7rP+oSCal70g==", + "license": "MIT", + "dependencies": { + "core-js": "^2.6.12" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ciscospark/test-users-legacy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ciscospark/test-users-legacy/-/test-users-legacy-1.2.0.tgz", + "integrity": "sha512-WEAe6ntEZOk3TPzk7BGyattgh9OZnKPYNb9idfZnI3Dkb9iO3zUB3AlCqrAMp1I6dQ5+RTkgTuSGdgWP4Toluw==", + "license": "UNLICENSED", + "optional": true, + "dependencies": { + "btoa": "^1.1.2", + "lodash": "^4.17.4", + "node-random-name": "^1.0.1", + "request": "^2.81.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@expo/cli": { + "version": "57.0.4", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-57.0.4.tgz", + "integrity": "sha512-7d+YW9PdGqgNI4dh9FTv+ZNE2xu1jV8xREDgl/7jiKNcOKdgby6ZAXufZX7iRotyxyu8fwjzETKMg7MkmYLJ8A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/code-signing-certificates": "^0.0.6", + "@expo/config": "~57.0.2", + "@expo/config-plugins": "~57.0.2", + "@expo/devcert": "^1.2.1", + "@expo/env": "~2.4.1", + "@expo/image-utils": "^0.11.1", + "@expo/inline-modules": "^0.1.1", + "@expo/json-file": "^11.0.0", + "@expo/log-box": "^57.0.0", + "@expo/metro": "~56.0.0", + "@expo/metro-config": "~57.0.3", + "@expo/metro-file-map": "^57.0.0", + "@expo/osascript": "^2.7.0", + "@expo/package-manager": "^1.13.0", + "@expo/plist": "^0.8.0", + "@expo/prebuild-config": "^57.0.4", + "@expo/require-utils": "^57.0.1", + "@expo/router-server": "^57.0.1", + "@expo/schema-utils": "^57.0.1", + "@expo/spawn-async": "^1.8.0", + "@expo/ws-tunnel": "^2.0.0", + "@expo/xcpretty": "^4.4.4", + "@react-native/dev-middleware": "0.86.0", + "accepts": "^1.3.8", + "agent-cli-detector": "^0.1.2", + "arg": "^5.0.2", + "bplist-creator": "0.1.0", + "bplist-parser": "^0.3.1", + "chalk": "^4.0.0", + "ci-info": "^3.3.0", + "compression": "^1.7.4", + "connect": "^3.7.0", + "debug": "^4.3.4", + "dnssd-advertise": "^1.1.4", + "expo-server": "^57.0.0", + "fetch-nodeshim": "^0.4.10", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "lan-network": "^0.2.1", + "multitars": "^1.0.0", + "node-forge": "^1.3.3", + "npm-package-arg": "^11.0.0", + "ora": "^3.4.0", + "picomatch": "^4.0.4", + "pretty-format": "^29.7.0", + "progress": "^2.0.3", + "prompts": "^2.3.2", + "resolve-from": "^5.0.0", + "semver": "^7.6.0", + "send": "^0.19.0", + "slugify": "^1.3.4", + "stacktrace-parser": "^0.1.10", + "structured-headers": "^0.4.1", + "terminal-link": "^2.1.1", + "toqr": "^0.1.1", + "wrap-ansi": "^7.0.0", + "ws": "^8.12.1", + "zod": "^3.25.76" + }, + "bin": { + "expo-internal": "main.js" + }, + "peerDependencies": { + "expo": "*", + "expo-router": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "expo-router": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@expo/cli/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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/code-signing-certificates": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz", + "integrity": "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-forge": "^1.3.3" + } + }, + "node_modules/@expo/config": { + "version": "57.0.2", + "resolved": "https://registry.npmjs.org/@expo/config/-/config-57.0.2.tgz", + "integrity": "sha512-J/K4fBPs/wGMrK445Mz5fCuFhsOZjSEq+u7F0yCboCwQu+uPlkT/ZCi6/q5pOunFOTICFtLB5wfCKqf9Iz5iKA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/config-plugins": "~57.0.2", + "@expo/config-types": "^57.0.1", + "@expo/json-file": "^11.0.0", + "@expo/require-utils": "^57.0.1", + "deepmerge": "^4.3.1", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "resolve-workspace-root": "^2.0.0", + "semver": "^7.6.0", + "slugify": "^1.3.4" + } + }, + "node_modules/@expo/config-plugins": { + "version": "57.0.2", + "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-57.0.2.tgz", + "integrity": "sha512-85wEk9NKzdT25+UWEaSgF7gp9uR/GmtvrvQtGqZmyhFgVRNL2H3GdJOL4/50vyZh4JK69Hl7fWKGtARTN3B8Ag==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/config-types": "^57.0.1", + "@expo/json-file": "~11.0.0", + "@expo/plist": "^0.8.0", + "@expo/require-utils": "^57.0.1", + "@expo/sdk-runtime-versions": "^1.0.0", + "chalk": "^4.1.2", + "debug": "^4.3.5", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "semver": "^7.5.4", + "slugify": "^1.6.6", + "xcode": "^3.0.1", + "xml2js": "0.6.0" + } + }, + "node_modules/@expo/config-types": { + "version": "57.0.1", + "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-57.0.1.tgz", + "integrity": "sha512-fo7d/Ym28uwGzdTV2leEvpsb9t+7i8YHjy471m31+cmDt4BRd/l7e94JHyrXAq4SWOBVus16S0JLqm89SRCCdw==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@expo/devcert": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.2.1.tgz", + "integrity": "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/sudo-prompt": "^9.3.1", + "debug": "^3.1.0" + } + }, + "node_modules/@expo/devcert/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@expo/devtools": { + "version": "57.0.0", + "resolved": "https://registry.npmjs.org/@expo/devtools/-/devtools-57.0.0.tgz", + "integrity": "sha512-i8ITQmf/wB0JNQ2gASFOKvqo1zRWCl/VfPlFRXdz6UkHen4s31NmMy0zmumS+pMpwn0+gA6oU4FF4zRDRG488Q==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chalk": "^4.1.2" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@expo/dom-webview": { + "version": "57.0.0", + "resolved": "https://registry.npmjs.org/@expo/dom-webview/-/dom-webview-57.0.0.tgz", + "integrity": "sha512-zBZw52KnaHf9zGVp1eJk8kNfc+5ArGf+KvTL3SeMsr03K6tPJtLbgycVLjrAiLMfhzqGVjPD2G+rbNwpbLUxcg==", + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, + "node_modules/@expo/env": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.4.1.tgz", + "integrity": "sha512-3c9Mg9x0HmGPEsVrGAGyEDJsNUOZ55cZvZ47/HLmXh7MHV9Zv7My73wThklKrObaBBoMfE4YqpKjYKDRzojpjQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chalk": "^4.0.0", + "debug": "^4.3.4", + "getenv": "^2.0.0" + }, + "engines": { + "node": ">=20.12.0" + } + }, + "node_modules/@expo/expo-modules-macros-plugin": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@expo/expo-modules-macros-plugin/-/expo-modules-macros-plugin-0.3.0.tgz", + "integrity": "sha512-2tRq8kiIZTVZcI5uggh86HefQ7s++Zk5WkFFomNp4aUqyN5ownHHvj1jPEP9jWXaXjPDmWuf5SUZTGD5G6AKkg==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@expo/fingerprint": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.20.2.tgz", + "integrity": "sha512-8emNA6sG7UVEOhbvtsHHe4e/G7Xv/80Xt3Xhdqcg0ulRChTEDoXra7G1GqZeO0UXfXCzdpQl8RNKmWDOaB7gMA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/env": "^2.4.1", + "@expo/spawn-async": "^1.8.0", + "arg": "^5.0.2", + "chalk": "^4.1.2", + "debug": "^4.3.4", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "ignore": "^5.3.1", + "minimatch": "^10.2.2", + "resolve-from": "^5.0.0", + "semver": "^7.6.0" + }, + "bin": { + "fingerprint": "bin/cli.js" + } + }, + "node_modules/@expo/fingerprint/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@expo/fingerprint/node_modules/brace-expansion": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@expo/fingerprint/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@expo/fingerprint/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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/image-utils": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.11.1.tgz", + "integrity": "sha512-0JueH4vdgAZQmhlSYFvTQzt4b4NO5cnByDuApw7bMUIjhwLRnT46Ki3ritMrzJMQaO2lLK2flInZbsZbOuy8nw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/require-utils": "^57.0.1", + "@expo/spawn-async": "^1.8.0", + "chalk": "^4.0.0", + "getenv": "^2.0.0", + "jimp-compact": "0.16.1", + "parse-png": "^2.1.0", + "semver": "^7.6.0" + } + }, + "node_modules/@expo/inline-modules": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@expo/inline-modules/-/inline-modules-0.1.1.tgz", + "integrity": "sha512-Jbp1d6LSOS2RZCrNeK6JehcRGcYGb+1xNsHUfjggMWMlz/J2SP3HHKg8cbTkVj7KKPn33AkyFBaSqlMsvrp7ow==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/config-plugins": "~57.0.1" + } + }, + "node_modules/@expo/json-file": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-11.0.0.tgz", + "integrity": "sha512-pHJCETqFL5x5BzNV6cEPwjwuECgGmnl0bNmfHIJ6LM1tlh2eVXi5HEdit3zby/JO/B8Otk5cgcqtJXgvvUat3A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.20.0", + "json5": "^2.2.3" + } + }, + "node_modules/@expo/local-build-cache-provider": { + "version": "57.0.2", + "resolved": "https://registry.npmjs.org/@expo/local-build-cache-provider/-/local-build-cache-provider-57.0.2.tgz", + "integrity": "sha512-/8/FoYrEBJZPG4wR8kO6REI4VRCPAStD+7wS/Ds6XXddxhmyMP3pvUJz/c3icyAoqpbqeZZkR6E1ptT5Gi5iXg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/config": "~57.0.2", + "chalk": "^4.1.2" + } + }, + "node_modules/@expo/log-box": { + "version": "57.0.0", + "resolved": "https://registry.npmjs.org/@expo/log-box/-/log-box-57.0.0.tgz", + "integrity": "sha512-tt9x76IEE8hp2FWTLPfEArrTyD7GCoUe3TpohESy+SPZ/OqkUnSXz40xnUuE0XbE132z8c5CRCfXQLM9DTEknQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/dom-webview": "^57.0.0", + "anser": "^1.4.9", + "stacktrace-parser": "^0.1.10" + }, + "peerDependencies": { + "@expo/dom-webview": "^57.0.0", + "expo": "*", + "react": "*", + "react-native": "*" + } + }, + "node_modules/@expo/metro": { + "version": "56.0.0", + "resolved": "https://registry.npmjs.org/@expo/metro/-/metro-56.0.0.tgz", + "integrity": "sha512-5gIgQHtEpjjvsjKfVtIv23a98LLRV0/y07PDShEwYSytAMlE3FSF8RHXqtHc1sUJL6dn7hnuIBpIbrLXXuVi0A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "metro": "0.84.4", + "metro-babel-transformer": "0.84.4", + "metro-cache": "0.84.4", + "metro-cache-key": "0.84.4", + "metro-config": "0.84.4", + "metro-core": "0.84.4", + "metro-file-map": "0.84.4", + "metro-minify-terser": "0.84.4", + "metro-resolver": "0.84.4", + "metro-runtime": "0.84.4", + "metro-source-map": "0.84.4", + "metro-symbolicate": "0.84.4", + "metro-transform-plugins": "0.84.4", + "metro-transform-worker": "0.84.4" + } + }, + "node_modules/@expo/metro-config": { + "version": "57.0.3", + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-57.0.3.tgz", + "integrity": "sha512-k7qcjTe1xDrUW15Ue86WAsJSL0ubiSluBXVNRFoe9snAWhMzBGzdZfl9XiDf4TNUV43T0L1ch+n4GmDqamvfEg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.20.0", + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.5", + "@expo/config": "~57.0.2", + "@expo/env": "~2.4.1", + "@expo/json-file": "~11.0.0", + "@expo/metro": "~56.0.0", + "@expo/require-utils": "^57.0.1", + "@expo/spawn-async": "^1.8.0", + "@jridgewell/gen-mapping": "^0.3.13", + "@jridgewell/remapping": "^2.3.5", + "@jridgewell/sourcemap-codec": "^1.5.5", + "browserslist": "^4.25.0", + "chalk": "^4.1.0", + "debug": "^4.3.2", + "getenv": "^2.0.0", + "glob": "^13.0.0", + "hermes-parser": "^0.36.0", + "jsc-safe-url": "^0.2.4", + "lightningcss": "^1.30.1", + "picomatch": "^4.0.4", + "postcss": "^8.5.14", + "resolve-from": "^5.0.0" + }, + "peerDependencies": { + "expo": "*" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } + } + }, + "node_modules/@expo/metro-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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/metro-file-map": { + "version": "57.0.0", + "resolved": "https://registry.npmjs.org/@expo/metro-file-map/-/metro-file-map-57.0.0.tgz", + "integrity": "sha512-/sxwKQmwpYFYjFT6VYFpgldTwSv53OCx4/UCpLCv9iqQLVQ30hFEJsxGA9Jif8n9pacigK4P5/0ZJ2zMHm6arA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.3.4", + "fb-watchman": "^2.0.2", + "invariant": "^2.2.4", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "node_modules/@expo/osascript": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.7.0.tgz", + "integrity": "sha512-wKIXL8UtbuX4KwavPasIW3CUcgTbYfjzLcgUhjyKUAYDEqMaf6gmU1bqz3ffBPTokmX+G8/vFG1ZuI9etQWukA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/spawn-async": "^1.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@expo/package-manager": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.13.0.tgz", + "integrity": "sha512-s3W3eZafJDEyVL7W/jxj2Nz3eONKxSCU604S5xj8ijrVaRz83x0DnZznLf/UXQEI1w+FyibH68nHeQyk767b1A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/json-file": "^11.0.0", + "@expo/spawn-async": "^1.8.0", + "chalk": "^4.0.0", + "npm-package-arg": "^11.0.0", + "ora": "^3.4.0", + "resolve-workspace-root": "^2.0.0" + } + }, + "node_modules/@expo/plist": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.8.0.tgz", + "integrity": "sha512-24JlUJI4PwHN4PLydlzFEzCdiqybfaV5t04QBkOg8em3AjvHKbMgBGlKreiuOoc0rNa3DZ21ZqL+xLGMBLQNKQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + } + }, + "node_modules/@expo/prebuild-config": { + "version": "57.0.4", + "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-57.0.4.tgz", + "integrity": "sha512-wdyu9aOvU0/vW3U2/HgekQKrxh9v8Rqq74LNUXMsMFv+LeJz3MJfnexJNAL243/TwqEO396QRGqCe7ac11x/mw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/config": "~57.0.2", + "@expo/config-plugins": "~57.0.2", + "@expo/config-types": "^57.0.1", + "@expo/image-utils": "^0.11.1", + "@expo/json-file": "^11.0.0", + "@react-native/normalize-colors": "0.86.0", + "debug": "^4.3.1", + "expo-modules-autolinking": "~57.0.4", + "resolve-from": "^5.0.0", + "semver": "^7.6.0" + } + }, + "node_modules/@expo/prebuild-config/node_modules/expo-modules-autolinking": { + "version": "57.0.4", + "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-57.0.4.tgz", + "integrity": "sha512-O0G2WRw4xtPpuhwufo2HQ6fyVQhNxtUVmO+tJD3+dB3bIslQCz3pM+s8ouhkf7ZU97g/wZOrd33umuHbbZjM3g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/require-utils": "^57.0.1", + "@expo/spawn-async": "^1.8.0", + "chalk": "^4.1.0", + "commander": "^7.2.0" + }, + "bin": { + "expo-modules-autolinking": "bin/expo-modules-autolinking.js" + } + }, + "node_modules/@expo/prebuild-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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/require-utils": { + "version": "57.0.1", + "resolved": "https://registry.npmjs.org/@expo/require-utils/-/require-utils-57.0.1.tgz", + "integrity": "sha512-uXen5/4x7j60I5slShgZr5QEtJDBK8homFiNLDnDrNrxZhrRHXASo0H6JArs3/1PDzw1wahzhGWg2WKuYyZd0A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.20.0", + "@babel/core": "^7.25.2", + "@babel/plugin-transform-modules-commonjs": "^7.24.8" + }, + "peerDependencies": { + "typescript": "^5.0.0 || ^5.0.0-0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@expo/router-server": { + "version": "57.0.1", + "resolved": "https://registry.npmjs.org/@expo/router-server/-/router-server-57.0.1.tgz", + "integrity": "sha512-jZ+jHG34rRa8HyurTQq5r558dMcb77F3Mt0HMKotAJ8Wm5bJLULJsL3KVLkEVcYP254xI9zzeJVcN79Fck/nLQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.3.4" + }, + "peerDependencies": { + "@expo/metro-runtime": "^57.0.2", + "expo": "*", + "expo-constants": "^57.0.2", + "expo-font": "^57.0.0", + "expo-router": "*", + "expo-server": "^57.0.0", + "react": "*", + "react-dom": "*", + "react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1" + }, + "peerDependenciesMeta": { + "@expo/metro-runtime": { + "optional": true + }, + "expo-router": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-server-dom-webpack": { + "optional": true + } + } + }, + "node_modules/@expo/schema-utils": { + "version": "57.0.1", + "resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-57.0.1.tgz", + "integrity": "sha512-IVdaqtP3+iHFRE/y22mKijQtZanLcB18q1zi2kfN6RINTCryyzM7qHGsWHc5LBJbOuj1G4avCOECs97hOJm0GQ==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@expo/sdk-runtime-versions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz", + "integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@expo/spawn-async": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.8.0.tgz", + "integrity": "sha512-eb9xxd/LbuEGSdua4NumCu/McVB9EM+F/JxB9pWgnERw4HQ9XyTNH1KapG6oqLWR8TuRK2LQfzJlmNi94CVobw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "cross-spawn": "^7.0.6" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@expo/sudo-prompt": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@expo/sudo-prompt/-/sudo-prompt-9.3.2.tgz", + "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@expo/ws-tunnel": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-2.0.0.tgz", + "integrity": "sha512-j+JfTRdCk820J9dU0sA2SqshQIKFOMo7ED84w9MJFcebfbNQgsLztEY/SABDkGnjatrW4xGqnUhVRxSBVyCkXw==", + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "ws": "^8.0.0" + } + }, + "node_modules/@expo/xcpretty": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.4.tgz", + "integrity": "sha512-4aQzz9vgxcNXFfo/iyNgDDYfsU5XGKKxWxZopw0cVotHiW+U8IJbIxMaxsINs6bHhtkG3StKNPcOrn3eBuxKPw==", + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.20.0", + "chalk": "^4.1.0", + "js-yaml": "^4.1.0" + }, + "bin": { + "excpretty": "build/cli.js" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/ttlcache": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz", + "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==", + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "optional": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.8.0.tgz", + "integrity": "sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q==", + "license": "MIT", + "dependencies": { + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-schema/node_modules/asn1js": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", + "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==", + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.5", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@peculiar/json-schema": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", + "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@peculiar/utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz", + "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/webcrypto": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.7.1.tgz", + "integrity": "sha512-ODOov0sGMJMf3jPonOkgGqPknTsu+DdQ7kD++gz8aI+aFMOMHFbWAA2taqXXVTdP+OTOQR/znGvSpmkeI0WTYQ==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.7.0", + "@peculiar/json-schema": "^1.1.12", + "@peculiar/utils": "^2.0.2", + "tslib": "^2.8.1", + "webcrypto-core": "^1.9.2" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/@react-native/assets-registry": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.86.0.tgz", + "integrity": "sha512-nIaXbm2jX1OTYp0qbviJ3O6KZivoE8z3BnhUQ2LsqfZSWRoOK/n1qsiAr6oALiNKWnXY3j2KPwtYORnZzp8xew==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/@react-native/babel-plugin-codegen": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.86.0.tgz", + "integrity": "sha512-qdsABWNW7uTll90l4Vh03gjeyu3WVDi2CyiiyvYGMRDcoYbjbQi6df3BMAm9lQI2yslZ1T14LlDDAsgTwNxplA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/traverse": "^7.29.0", + "@react-native/codegen": "0.86.0" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/@react-native/codegen": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.86.0.tgz", + "integrity": "sha512-uTs9DBo3+/lUqinsGZK0FKJRBVClrwMXoZToaDxE1Q2SL2e55vs2GwyZfIKzPl5uJnbu4PfFMIp0/mLXLWUMuA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/parser": "^7.29.0", + "hermes-parser": "0.36.0", + "invariant": "^2.2.4", + "nullthrows": "^1.1.1", + "tinyglobby": "^0.2.15", + "yargs": "^17.6.2" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, + "node_modules/@react-native/codegen/node_modules/hermes-estree": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.36.0.tgz", + "integrity": "sha512-A1+8zn5oss2CFP7pKsOaxorQG6FNIz1WU1VDqruLPPZl3LVgeE2C5xfFg8Ow6/Ow4mSslLLtYP1J3n38eKyW9w==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@react-native/codegen/node_modules/hermes-parser": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.36.0.tgz", + "integrity": "sha512-GdpwMmH5x6IpC1cijvcvYnlPB60Mh6kTSF/NFdYV/j56gYdi+0RIakYs+eqOV+bbO0SW7mgVVGSsTJxyPQfo3w==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "hermes-estree": "0.36.0" + } + }, + "node_modules/@react-native/community-cli-plugin": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.86.0.tgz", + "integrity": "sha512-Jv8p1ebEPfTzs8gmrjsdT2XMXFfeAg45Pman+XPLFGaSeGAZkutRFRyX9Cs9aGTSOyIA9YPJ6vDNb1ayTf1FKQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@react-native/dev-middleware": "0.86.0", + "debug": "^4.4.0", + "invariant": "^2.2.4", + "metro": "^0.84.3", + "metro-config": "^0.84.3", + "metro-core": "^0.84.3", + "semver": "^7.1.3" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + }, + "peerDependencies": { + "@react-native-community/cli": "*", + "@react-native/metro-config": "0.86.0" + }, + "peerDependenciesMeta": { + "@react-native-community/cli": { + "optional": true + }, + "@react-native/metro-config": { + "optional": true + } + } + }, + "node_modules/@react-native/debugger-frontend": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.86.0.tgz", + "integrity": "sha512-7Mb3nDfyJeys+ELF75Ageu7VKERlnIMoO+aNPoXqTXvz+b41L6l2CqMyLpDHxkBSlenij6gEepPNgaIyWHbJZw==", + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/@react-native/debugger-shell": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@react-native/debugger-shell/-/debugger-shell-0.86.0.tgz", + "integrity": "sha512-Y0zEkZzLz8ou6o/VLml1A31X/rMgc6DRjwxwzPMa94qRTMY070WeBCNTITQo4kKTBAUgbxh07oXPQqp0Tpja8w==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "cross-spawn": "^7.0.6", + "debug": "^4.4.0", + "fb-dotslash": "0.5.8" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/@react-native/dev-middleware": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.86.0.tgz", + "integrity": "sha512-20pTO6yTybmvXvro520H6C7jydIQnLKOl5qFtVEcHSdFrY63r3OGei+Rx9bILgSRmH6jgnfEcijcMx7pwWuQtw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@isaacs/ttlcache": "^1.4.1", + "@react-native/debugger-frontend": "0.86.0", + "@react-native/debugger-shell": "0.86.0", + "chrome-launcher": "^0.15.2", + "chromium-edge-launcher": "^0.3.0", + "connect": "^3.6.5", + "debug": "^4.4.0", + "invariant": "^2.2.4", + "nullthrows": "^1.1.1", + "open": "^7.0.3", + "serve-static": "^1.16.2", + "ws": "^7.5.10" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/@react-native/dev-middleware/node_modules/ws": { + "version": "7.5.11", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", + "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==", + "license": "MIT", + "optional": true, + "peer": true, + "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/@react-native/gradle-plugin": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.86.0.tgz", + "integrity": "sha512-a1RcfaEDqWExCGfCwadIxt4l8FvKYgFqeMf2uzeKyAOnb+vTGNIeCvifFL2MqvgaeYxlER437HbMIajGcuJ1pQ==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/@react-native/js-polyfills": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.86.0.tgz", + "integrity": "sha512-zYy/Cjd1VTnZ2iCNaG9bDF9C3l2ntESiPRscjIlI5FKugu6aeTwsDSv1aI8Bc4Kp3vEdoVg+UQhLAhE4svREaQ==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/@react-native/normalize-colors": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.86.0.tgz", + "integrity": "sha512-kG0wfCGghUKlfxkJyyHCDVutWVYWK7/DG58ojA/4v9EfulgF+osuSQmlbNb3rcKX58qutm7JcldSeVLgGFha9g==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@react-native/virtualized-lists": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.86.0.tgz", + "integrity": "sha512-4/ZLXdf/OSpPDVO0AsQ1SJdRIzt5t9BNQ46QwGgxvX7/cirYR5k8KXctNGGgW8lQo2gZChEfY2zFCZg9nM/jiw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "invariant": "^2.2.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + }, + "peerDependencies": { + "@types/react": "^19.2.0", + "react": "*", + "react-native": "0.86.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", + "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.0.tgz", + "integrity": "sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "undici-types": "~8.3.0" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.2.tgz", + "integrity": "sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA==", + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/@unimodules/core": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@unimodules/core/-/core-7.2.0.tgz", + "integrity": "sha512-Nu+bAd/xG4B2xyYMrmV3LnDr8czUQgV1XhoL3sOOMwGydDJtfpWNodGhPhEMyKq2CXo4X7DDIo8qG6W2fk6XAQ==", + "deprecated": "replaced by the 'expo' package, learn more: https://blog.expo.dev/whats-new-in-expo-modules-infrastructure-7a7cdda81ebc", + "license": "MIT", + "optional": true, + "dependencies": { + "expo-modules-core": "~0.4.0" + } + }, + "node_modules/@unimodules/react-native-adapter": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@unimodules/react-native-adapter/-/react-native-adapter-6.5.0.tgz", + "integrity": "sha512-F2J6gVw9a57DTVTQQunp64fqD4HVBkltOpUz1L5lEccNbQlZEA7SjnqKJzXakI7uPhhN76/n+SGb7ihzHw2swQ==", + "deprecated": "replaced by the 'expo' package, learn more: https://blog.expo.dev/whats-new-in-expo-modules-infrastructure-7a7cdda81ebc", + "license": "MIT", + "optional": true, + "dependencies": { + "expo-modules-autolinking": "^0.3.2", + "expo-modules-core": "~0.4.0" + } + }, + "node_modules/@webex/common": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/common/-/common-2.60.0.tgz", + "integrity": "sha512-o6dbes91uqxLO9gjafIl46ycQVpzFmsENTldFh0uFb0LbT2ONX9DRO6599nS6Jd9xa4g+R2DoNHMJSwvj2Zjgw==", + "license": "MIT", + "dependencies": { + "backoff": "^2.5.0", + "bowser": "^2.11.0", + "core-decorators": "^0.20.0", + "global": "^4.4.0", + "lodash": "^4.17.21", + "safe-buffer": "^5.2.0", + "urlsafe-base64": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/common-timers": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/common-timers/-/common-timers-2.60.0.tgz", + "integrity": "sha512-DvxvEYGuqM80sH1y+YdB+u4Bl7dqle6FIP0FsE+N5k4bCWbred+yDy7ZmuLZ4a1SK/SSLxSBTo+VzIWk6Oithw==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/helper-html": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/helper-html/-/helper-html-2.60.0.tgz", + "integrity": "sha512-qyKsajx8gNZkZnp21LasfTiKoxqaIYzYgT9XvEL0QRmQOJZWxZIzYFQQVDOa2UgULC721xTLfdnCriSL5Qfn3w==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/helper-image": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/helper-image/-/helper-image-2.60.0.tgz", + "integrity": "sha512-2q0ZZyDegBeMv5DIW0VORf8WYmTNgAAv7MeRAzM+kvurBDE+yJabqoBXYj+nf5lSUjEOUnWwWtgFOELnN+YwbQ==", + "license": "MIT", + "dependencies": { + "@webex/http-core": "2.60.0", + "@webex/test-helper-chai": "2.60.0", + "@webex/test-helper-file": "2.60.0", + "@webex/test-helper-mocha": "2.60.0", + "exifr": "^5.0.3", + "gm": "^1.23.1", + "lodash": "^4.17.21", + "mime": "^2.4.4", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/http-core": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/http-core/-/http-core-2.60.0.tgz", + "integrity": "sha512-z+GHjx3d4Q0exVIfLex2iS1wYpkYscctIHiK1CPInivubpgtvt04E/qETtDV1iCo8wxhyzG2eAW/n0FcA7rdJQ==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/test-helper-test-users": "2.60.0", + "@webex/webex-core": "2.60.0", + "file-type": "^16.0.1", + "global": "^4.4.0", + "is-function": "^1.0.1", + "lodash": "^4.17.21", + "parse-headers": "^2.0.2", + "qs": "^6.7.3", + "request": "^2.88.0", + "safe-buffer": "^5.2.0", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-media-core": { + "version": "0.0.7-beta", + "resolved": "https://registry.npmjs.org/@webex/internal-media-core/-/internal-media-core-0.0.7-beta.tgz", + "integrity": "sha512-GxSRFKDdvL/gzZ67aIO2378kbVWAeGUQk5/pUprPcdY0cC4T6aoXa7AiLV+HiFmJSChPzBYZbOlFY49oSndgww==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.9", + "@webex/ts-sdp": "^1.0.1", + "detectrtc": "^1.4.1", + "events": "^3.3.0", + "sdp-transform": "^2.14.1", + "typed-emitter": "^2.1.0", + "uuid": "^8.3.2", + "webrtc-adapter": "^8.1.1", + "xstate": "^4.30.6" + }, + "engines": { + "node": ">=14.x" + } + }, + "node_modules/@webex/internal-media-core/node_modules/sdp": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.2.tgz", + "integrity": "sha512-xZocWwfyp4hkbN4hLWxMjmv2Q8aNa9MhmOZ7L9aCZPT+dZsgRr6wZRrSYE3HTdyk/2pZKPSgqI7ns7Een1xMSA==", + "license": "MIT" + }, + "node_modules/@webex/internal-media-core/node_modules/webrtc-adapter": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-8.2.4.tgz", + "integrity": "sha512-VwtwbYNKnVQW8koB9qb8YcxNwpSVHTvvKEZLzY6uQ3gFrA9E87VPbB5xE+m1AGwUjL1UgN35jRR9hQgteZI5bg==", + "license": "BSD-3-Clause", + "dependencies": { + "sdp": "^3.2.0" + }, + "engines": { + "node": ">=6.0.0", + "npm": ">=3.10.0" + } + }, + "node_modules/@webex/internal-plugin-calendar": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-calendar/-/internal-plugin-calendar-2.60.0.tgz", + "integrity": "sha512-xcT60Q2TKXvDJ6szQeXOAP5fygtZR6i2Ol5TOtqla3n9tpEGBSdUz8WTjVr/3A1TPkyLHRBcC1wxCKkWuuYDWQ==", + "license": "MIT", + "dependencies": { + "@webex/internal-plugin-conversation": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/internal-plugin-encryption": "2.60.0", + "@webex/webex-core": "2.60.0", + "lodash": "^4.17.21", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-calendar/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/internal-plugin-conversation": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-conversation/-/internal-plugin-conversation-2.60.0.tgz", + "integrity": "sha512-1VzUBMLcdw/dBC8BjARHsHr+guOuSgIRYksHVGa63nk0b3yQskP0jWTigYv0/G1TdBGzYB0UCrtpYgNYdd06ww==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/helper-html": "2.60.0", + "@webex/helper-image": "2.60.0", + "@webex/internal-plugin-encryption": "2.60.0", + "@webex/internal-plugin-user": "2.60.0", + "@webex/webex-core": "2.60.0", + "crypto-js": "^4.1.1", + "lodash": "^4.17.21", + "node-scr": "^0.3.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-conversation/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/internal-plugin-device": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-device/-/internal-plugin-device-2.60.0.tgz", + "integrity": "sha512-FmrRARGLGvb276LQpTG5u8mKo8mGrrHG+UcXvzu2sU7+p/7Wgm+z/izshJJC55SFWF77gV8oR3sAcTYwZMnqKw==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/common-timers": "2.60.0", + "@webex/http-core": "2.60.0", + "@webex/internal-plugin-metrics": "2.60.0", + "@webex/webex-core": "2.60.0", + "ampersand-collection": "^2.0.2", + "ampersand-state": "^5.0.3", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-encryption": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-encryption/-/internal-plugin-encryption-2.60.0.tgz", + "integrity": "sha512-NvKJUvoRhV2b737nuYq/mWkvqD8ZOM3rCVqY+MhxXXqantHu3jqxfvZ86O3r++Mfyob201C8N0HtwzdupCM4yg==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/common-timers": "2.60.0", + "@webex/http-core": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/internal-plugin-mercury": "2.60.0", + "@webex/test-helper-file": "2.60.0", + "@webex/webex-core": "2.60.0", + "asn1js": "^2.0.26", + "debug": "^4.3.4", + "isomorphic-webcrypto": "^2.3.8", + "lodash": "^4.17.21", + "node-jose": "^2.2.0", + "node-kms": "^0.4.0", + "node-scr": "^0.3.0", + "pkijs": "^2.1.84", + "safe-buffer": "^5.2.0", + "uuid": "^3.3.2", + "valid-url": "^1.0.9" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-encryption/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/internal-plugin-feature": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-feature/-/internal-plugin-feature-2.60.0.tgz", + "integrity": "sha512-ble2sAAveXbGdee1QboU3ZCoDT71iWwaGNld/5WSdEpsNKO9sV5WC5Neo3oq8SmKiYSdLoEEYFC5J+9B26Bkdg==", + "license": "MIT", + "dependencies": { + "@webex/internal-plugin-device": "2.60.0", + "@webex/internal-plugin-mercury": "2.60.0", + "@webex/webex-core": "2.60.0", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-locus": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-locus/-/internal-plugin-locus-2.60.0.tgz", + "integrity": "sha512-r0LSnwk+9dDMp/pGflx+c+gX1CPDo06j4dMhRbkLkJTqqhC+uAnvHREVIQuITViwY9cf+Izm9On3xh6SDqHglw==", + "license": "MIT", + "dependencies": { + "@webex/internal-plugin-mercury": "2.60.0", + "@webex/test-helper-chai": "2.60.0", + "@webex/test-helper-mock-webex": "2.60.0", + "@webex/webex-core": "2.60.0", + "lodash": "^4.17.21", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-locus/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/internal-plugin-lyra": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-lyra/-/internal-plugin-lyra-2.60.0.tgz", + "integrity": "sha512-OSMl+sh2hvWMHw0kd+MdVeJa2coKCPlzk89+BLU51DYrgc+6DvBGOFegNNqRa+a1Z5iJtKB7Q5gI5Xq/baZmtg==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-plugin-conversation": "2.60.0", + "@webex/internal-plugin-encryption": "2.60.0", + "@webex/internal-plugin-feature": "2.60.0", + "@webex/internal-plugin-locus": "2.60.0", + "@webex/internal-plugin-mercury": "2.60.0", + "@webex/webex-core": "2.60.0", + "bowser": "^2.11.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-lyra/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/internal-plugin-mercury": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-mercury/-/internal-plugin-mercury-2.60.0.tgz", + "integrity": "sha512-TMKhtWsuC+glUDWEtiTRJTPF/1IS9MVV7zEAP1bqgVsdI9b6iV1k+p72il5Q2i+ynksdbuzg0Pd4cM28pO7hwA==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/common-timers": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/internal-plugin-feature": "2.60.0", + "@webex/internal-plugin-metrics": "2.60.0", + "@webex/test-helper-chai": "2.60.0", + "@webex/test-helper-mocha": "2.60.0", + "@webex/test-helper-mock-web-socket": "2.60.0", + "@webex/test-helper-mock-webex": "2.60.0", + "@webex/test-helper-refresh-callback": "2.60.0", + "@webex/test-helper-test-users": "2.60.0", + "@webex/webex-core": "2.60.0", + "backoff": "^2.5.0", + "lodash": "^4.17.21", + "uuid": "^3.3.2", + "ws": "^8.2.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-mercury/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/internal-plugin-metrics": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-metrics/-/internal-plugin-metrics-2.60.0.tgz", + "integrity": "sha512-AKTUnVoGtP2ib3ui5cY00f61TVRtsNwfg2QXJ0uIRHU9w1FbC0rY4M3eJ+ssOJAGtrSa1InmDO5KFdmHuvHP8g==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/common-timers": "2.60.0", + "@webex/test-helper-chai": "2.60.0", + "@webex/test-helper-mock-webex": "2.60.0", + "@webex/webex-core": "2.60.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-presence": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-presence/-/internal-plugin-presence-2.60.0.tgz", + "integrity": "sha512-3dd+JdGFvVUrPugDD2KhhhzjHGsg/lhXOsndPf7kZNPq9a1si0EX70R3ig4RyXostsmunRtNp9DaSlBKmg8J6g==", + "license": "MIT", + "dependencies": { + "@webex/internal-plugin-device": "2.60.0", + "@webex/internal-plugin-mercury": "2.60.0", + "@webex/test-helper-chai": "2.60.0", + "@webex/test-helper-mocha": "2.60.0", + "@webex/test-helper-mock-webex": "2.60.0", + "@webex/test-helper-test-users": "2.60.0", + "@webex/webex-core": "2.60.0", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-search": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-search/-/internal-plugin-search-2.60.0.tgz", + "integrity": "sha512-e4lXYHPdl1Qa+lA5ojjhWZWT1avakjGUK42OU5j9kQfi1IQ/sbdpyAlISwjTvm0qJ2G8ImcQJUwddxaGv991nA==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-plugin-conversation": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/internal-plugin-encryption": "2.60.0", + "@webex/webex-core": "2.60.0", + "lodash": "^4.17.21", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-search/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/internal-plugin-support": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-support/-/internal-plugin-support-2.60.0.tgz", + "integrity": "sha512-eiiH8Pr/HaCvhdQy66mmIqES8/096xyBYWCLvxleWJ32PfJ/TFZcDJbaC+odSKb3dCQyqBcx4QsNa1JFLYRW+w==", + "license": "MIT", + "dependencies": { + "@webex/internal-plugin-device": "2.60.0", + "@webex/internal-plugin-search": "2.60.0", + "@webex/test-helper-chai": "2.60.0", + "@webex/test-helper-file": "2.60.0", + "@webex/test-helper-mock-webex": "2.60.0", + "@webex/test-helper-test-users": "2.60.0", + "@webex/webex-core": "2.60.0", + "lodash": "^4.17.21", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-support/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/internal-plugin-user": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/internal-plugin-user/-/internal-plugin-user-2.60.0.tgz", + "integrity": "sha512-kl6IP4NxQ3EJI8CCIF4lY5OJM6M+sTaUadFdvMlZqOaG1zNbXIH9BuClB3xXdJVlO9Cmkbew1iuRabASODFoKg==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/test-helper-chai": "2.60.0", + "@webex/test-helper-mock-webex": "2.60.0", + "@webex/test-helper-test-users": "2.60.0", + "@webex/webex-core": "2.60.0", + "lodash": "^4.17.21", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/internal-plugin-user/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/plugin-attachment-actions": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-attachment-actions/-/plugin-attachment-actions-2.60.0.tgz", + "integrity": "sha512-qeR+B/RwXpCIVB967NmSEKBzqhvB6jN8FyYI5MySNZ76KG/nsH9Ys9zsWi4I7ilj8AsRVuxc7+YwY/B1wMXHIA==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-plugin-conversation": "2.60.0", + "@webex/internal-plugin-mercury": "2.60.0", + "@webex/plugin-logger": "2.60.0", + "@webex/plugin-messages": "2.60.0", + "@webex/plugin-people": "2.60.0", + "@webex/test-helper-chai": "2.60.0", + "@webex/test-helper-test-users": "2.60.0", + "@webex/webex-core": "2.60.0", + "debug": "^4.3.4", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-authorization": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-authorization/-/plugin-authorization-2.60.0.tgz", + "integrity": "sha512-WqijIyG1Fy4LOOa31hcTtzzbK9xM2eFOG+2YBbPxPCsjJBGeS2PTyt/c3kvmaufTpFKbB8NGYF96PWL03NIgrQ==", + "license": "MIT", + "dependencies": { + "@webex/plugin-authorization-browser": "2.60.0", + "@webex/plugin-authorization-node": "2.60.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-authorization-browser": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-authorization-browser/-/plugin-authorization-browser-2.60.0.tgz", + "integrity": "sha512-OdG6o0w/kUiJPPGPZR0PYWmEAJxESN3YcgiLFCsT1/LU2iZjtwQ3Hk8SxtGw4ueG7zxlsIKI9uHYKLIDlflkAg==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/plugin-authorization-node": "2.60.0", + "@webex/storage-adapter-local-storage": "2.60.0", + "@webex/storage-adapter-spec": "2.60.0", + "@webex/webex-core": "2.60.0", + "jose": "^4.13.1", + "lodash": "^4.17.21", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-authorization-browser/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/plugin-authorization-node": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-authorization-node/-/plugin-authorization-node-2.60.0.tgz", + "integrity": "sha512-Kd8EnG3eQ8fdogjr0S/wCGPsY8rY37nM2kFuPtzv6d8YjzUcNMaW/3yhLMr2BbOx3o9JKptQHUNx5q7dm1CnnA==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/webex-core": "2.60.0", + "jsonwebtoken": "^9.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-authorization-node/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/plugin-device-manager": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-device-manager/-/plugin-device-manager-2.60.0.tgz", + "integrity": "sha512-Q3GpsS9RLx5KUfU8I+9QXbD2OVY5aEdkXDRW80IYavFgm//vWynw5/yNtHF/Er1JyhHJY2jJepk2bsoMoyNoug==", + "license": "MIT", + "dependencies": { + "@webex/internal-plugin-calendar": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/internal-plugin-lyra": "2.60.0", + "@webex/internal-plugin-search": "2.60.0", + "@webex/plugin-authorization": "2.60.0", + "@webex/plugin-logger": "2.60.0", + "@webex/test-helper-chai": "2.60.0", + "@webex/webex-core": "2.60.0", + "lodash": "^4.17.21", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-device-manager/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/plugin-logger": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-logger/-/plugin-logger-2.60.0.tgz", + "integrity": "sha512-0FtUyW3T53tO7DBkSRZpKfugR2nSE1nklg4p1JWZIGRASAjCCBmShE0J0eedTO9zhiWtNuABdRUph5HfxxM32A==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/test-helper-chai": "2.60.0", + "@webex/test-helper-mocha": "2.60.0", + "@webex/test-helper-mock-webex": "2.60.0", + "@webex/webex-core": "2.60.0", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-meetings": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-meetings/-/plugin-meetings-2.60.0.tgz", + "integrity": "sha512-DjUNzL4wni1Q5UcyaO66gXOLnfF2e69zulwxGPAUuvfjUQ2kn08gWymKE0YNw0PwbvM5RjMF5matYQI7NvhlnA==", + "license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-media-core": "0.0.7-beta", + "@webex/internal-plugin-device": "2.60.0", + "@webex/internal-plugin-metrics": "2.60.0", + "@webex/internal-plugin-support": "2.60.0", + "@webex/internal-plugin-user": "2.60.0", + "@webex/plugin-people": "2.60.0", + "@webex/ts-sdp": "1.0.1", + "@webex/webex-core": "2.60.0", + "bowser": "^2.11.0", + "btoa": "^1.2.1", + "dotenv": "^4.0.0", + "global": "^4.4.0", + "ip-anonymize": "^0.1.0", + "javascript-state-machine": "^3.1.0", + "lodash": "^4.17.21", + "sdp-transform": "^2.12.0", + "uuid": "^3.3.2", + "webrtc-adapter": "^7.7.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-meetings/node_modules/dotenv": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", + "integrity": "sha512-XcaMACOr3JMVcEv0Y/iUM2XaOsATRZ3U1In41/1jjK6vJZ2PZbQ1bzCG8uvaByfaBpl9gqc9QWJovpUGBXLLYQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.6.0" + } + }, + "node_modules/@webex/plugin-meetings/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/plugin-memberships": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-memberships/-/plugin-memberships-2.60.0.tgz", + "integrity": "sha512-b0Vmxtx++wkSjg/BpmUYGFcTqs+5ULxgG3YVHf6ttB0Fsr4U1AGHGwXoVNDIgxnpqP9S23lcDPgAYL47EKdsNA==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-plugin-conversation": "2.60.0", + "@webex/internal-plugin-mercury": "2.60.0", + "@webex/plugin-logger": "2.60.0", + "@webex/plugin-messages": "2.60.0", + "@webex/plugin-people": "2.60.0", + "@webex/plugin-rooms": "2.60.0", + "@webex/webex-core": "2.60.0", + "debug": "^4.3.4", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-messages": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-messages/-/plugin-messages-2.60.0.tgz", + "integrity": "sha512-iZI5edGSUc7CAheMtkUCZHnqRs5oB3DKKznkcRfob3dY6uemop1wEv6PsWYdrHAu3Aage74cJ5p7XcAkHHxLsw==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-plugin-conversation": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/internal-plugin-mercury": "2.60.0", + "@webex/plugin-logger": "2.60.0", + "@webex/plugin-people": "2.60.0", + "@webex/plugin-rooms": "2.60.0", + "@webex/webex-core": "2.60.0", + "debug": "^4.3.4", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-people": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-people/-/plugin-people-2.60.0.tgz", + "integrity": "sha512-nr+FuF4mnV8vfAQeqzJguu5c7rHjEd0G86f9dyS0EHdZoHr41ggNK1QDcxuguZHSB5fdkn7tLqC5vpKdj8fmMA==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-plugin-mercury": "2.60.0", + "@webex/webex-core": "2.60.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-rooms": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-rooms/-/plugin-rooms-2.60.0.tgz", + "integrity": "sha512-nv5UAomq1NWpO8beoLP6YOd5l5Tj7CO2ShJ/F0d7t6StOIUmoJZtEV8KGytaEwmxB2mI/ppXrU6Sb0SrNGoY/g==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/internal-plugin-conversation": "2.60.0", + "@webex/internal-plugin-mercury": "2.60.0", + "@webex/plugin-logger": "2.60.0", + "@webex/plugin-memberships": "2.60.0", + "@webex/plugin-messages": "2.60.0", + "@webex/plugin-people": "2.60.0", + "@webex/webex-core": "2.60.0", + "debug": "^4.3.4", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-team-memberships": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-team-memberships/-/plugin-team-memberships-2.60.0.tgz", + "integrity": "sha512-XLfH7NZvuOOqsZ5ghNGAxoAlDaCRap1uOqCCpDhJkDdM57S9jAKmdYReXH6ucJun4KNdV05h0sDOM5NGvbxzqg==", + "license": "MIT", + "dependencies": { + "@webex/internal-plugin-device": "2.60.0", + "@webex/plugin-logger": "2.60.0", + "@webex/plugin-rooms": "2.60.0", + "@webex/plugin-teams": "2.60.0", + "@webex/webex-core": "2.60.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-teams": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-teams/-/plugin-teams-2.60.0.tgz", + "integrity": "sha512-tLQD56T393OROG2rLJAaaVZVmy0tZeMNJkJTQypwO3d8u/anMHeypgTqINrpD/B+QB7sO+F5IsP3HT+70MVbQg==", + "license": "MIT", + "dependencies": { + "@webex/internal-plugin-device": "2.60.0", + "@webex/plugin-logger": "2.60.0", + "@webex/plugin-memberships": "2.60.0", + "@webex/plugin-rooms": "2.60.0", + "@webex/test-helper-chai": "2.60.0", + "@webex/test-helper-test-users": "2.60.0", + "@webex/webex-core": "2.60.0", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/plugin-webhooks": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/plugin-webhooks/-/plugin-webhooks-2.60.0.tgz", + "integrity": "sha512-NCiiXPudHh6X+MkGnRAumFgqadMGQ5t6k8h+DE1lGME3ujVp7dO0L+ujbiA8K3ylywk8f6AN0vRim3wvN4wPDQ==", + "license": "MIT", + "dependencies": { + "@webex/internal-plugin-device": "2.60.0", + "@webex/plugin-logger": "2.60.0", + "@webex/plugin-rooms": "2.60.0", + "@webex/webex-core": "2.60.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/storage-adapter-local-storage": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/storage-adapter-local-storage/-/storage-adapter-local-storage-2.60.0.tgz", + "integrity": "sha512-1L48cIY0IyEzR2pqVhJAFwjBKP7ZiY/Dfs9xeFQ25l9d2Qa1n4uFBorA9v7JYSjpU61/APIIdUuciHfEWFvtOQ==", + "license": "MIT", + "dependencies": { + "@webex/storage-adapter-spec": "2.60.0", + "@webex/test-helper-mocha": "2.60.0", + "@webex/webex-core": "2.60.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/storage-adapter-spec": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/storage-adapter-spec/-/storage-adapter-spec-2.60.0.tgz", + "integrity": "sha512-ovd2YB85qEPnKWjoKj9OcZlefhdWBSlDCD6TSD31zM3kPJ8P85yIG8Cg9z7fSi5eB7zKHRIJii8Kh1M90Au72w==", + "license": "MIT", + "dependencies": { + "@webex/test-helper-chai": "2.60.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/test-helper-chai": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/test-helper-chai/-/test-helper-chai-2.60.0.tgz", + "integrity": "sha512-PM75a1rqP7O8IE/1IwosSL4UsND6bNClZzFNi8PGnW11BTCdzjlOz9zbUGiVtB5IO218CZ2KUAum6w2cWjHp0A==", + "license": "MIT", + "dependencies": { + "@webex/test-helper-file": "2.60.0", + "check-error": "^1.0.2", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/test-helper-file": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/test-helper-file/-/test-helper-file-2.60.0.tgz", + "integrity": "sha512-YVH+s3qqU0KWWDqu2kWsDbVX1cq11WB5j5H/x6+o8v19mbVO5ttqwiMaBEHBZ0t3xz0eo7EUfsL1QUlI/VcJJQ==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/test-helper-make-local-url": "2.60.0", + "es6-promise": "^4.2.8", + "file-type": "^16.0.1", + "xhr": "^2.5.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/test-helper-make-local-url": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/test-helper-make-local-url/-/test-helper-make-local-url-2.60.0.tgz", + "integrity": "sha512-uwk9tlrGaHqTi24F/Cpp4fUJKqAAH3+AiQ+onFbZ4+KbuRG7SamDrRdU0DK/3j7r80gLeuwqc1WKglmcZLfwnw==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/test-helper-mocha": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/test-helper-mocha/-/test-helper-mocha-2.60.0.tgz", + "integrity": "sha512-d8tq9LC9TRiY6I9+TAhSRUm5WMB+7rKqj2NYp80BGnUJ1IJUSji6r9ePUbhoLQsRtESFGc5Pkz0PmDQjMi5U5Q==", + "license": "MIT", + "dependencies": { + "bowser": "^2.11.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/test-helper-mock-web-socket": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/test-helper-mock-web-socket/-/test-helper-mock-web-socket-2.60.0.tgz", + "integrity": "sha512-J4MZmqq1ZMtb2Gb4nBMFrh+DmTXFVl8dsqUxiD2UqIxO1sfzNvhZK7EcWUsppsp/04k+wUmBQr0zaHWIAKvEQQ==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/test-helper-mock-webex": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/test-helper-mock-webex/-/test-helper-mock-webex-2.60.0.tgz", + "integrity": "sha512-syDORTuinBRPpiBIdl+fUuUWDqB1hdctRfoTX3T7hFSK+/LNPFKJSyjQ01D7jEdMPWoqELjkBPDyf9wVI03PbA==", + "license": "MIT", + "dependencies": { + "ampersand-state": "^5.0.3", + "es6-promise": "^4.2.8", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/test-helper-refresh-callback": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/test-helper-refresh-callback/-/test-helper-refresh-callback-2.60.0.tgz", + "integrity": "sha512-jNHdT2rME3/xFtgJwMux+W7HIo7GX8Q7W0O41Ua8tco0/hpSRkBL7jQ8EQxcj4E1UkQyn629LCqCpPO7RlqVXA==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/test-helper-retry": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/test-helper-retry/-/test-helper-retry-2.60.0.tgz", + "integrity": "sha512-e8+LJTuvEBkgXf3SxHPA1Tv+wD7StwGBX43BUdSwVjMOPEI7FLQ5d2uJZty/FqpYu7fcmv9iHSU2Tv0uFe0Jmw==", + "license": "MIT", + "dependencies": { + "es6-promise": "^4.2.8" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/test-helper-test-users": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/test-helper-test-users/-/test-helper-test-users-2.60.0.tgz", + "integrity": "sha512-Duv2AJz1Pi8PN/QCt7kALxLRV57uiKpPPJYtJklphdt/VSWbkRCuEWlu6bX4XAgVxQE46WTISJ1Zox303MyD+A==", + "license": "MIT", + "dependencies": { + "@webex/test-helper-retry": "2.60.0", + "@webex/test-users": "2.60.0", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "@ciscospark/test-users-legacy": "^1.0.2" + } + }, + "node_modules/@webex/test-users": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/test-users/-/test-users-2.60.0.tgz", + "integrity": "sha512-8lE97PC0uePV/QQ8L2D2mr+kIcNLB8H9TWgMhPZlCYAk9DaAJNQcVMYLQLkjYoD/e7kPcPpmuHIID/3q2Xjedg==", + "license": "MIT", + "dependencies": { + "@webex/http-core": "2.60.0", + "@webex/test-helper-mocha": "2.60.0", + "btoa": "^1.2.1", + "lodash": "^4.17.21", + "node-random-name": "^1.0.1", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/test-users/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@webex/ts-sdp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@webex/ts-sdp/-/ts-sdp-1.0.1.tgz", + "integrity": "sha512-dRbsF/MIS2bnnnbUMQL92SUZT3v9dhLJw2ItzGxqs9xaiVfEKVbjM020Hbd4ACQZ8dJ49CZ2tDd4Se9xUR3anQ==", + "license": "ISC" + }, + "node_modules/@webex/webex-core": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/@webex/webex-core/-/webex-core-2.60.0.tgz", + "integrity": "sha512-Tr18TdcsIsfD1TgJqF1O+BdshvNcDsFdNiHlCpVo5GhIrssOfxQr46sbLh0pCrGS9pDa4xx9YMgSEmqfFLY+6w==", + "license": "MIT", + "dependencies": { + "@webex/common": "2.60.0", + "@webex/common-timers": "2.60.0", + "@webex/http-core": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/plugin-logger": "2.60.0", + "@webex/storage-adapter-spec": "2.60.0", + "ampersand-collection": "^2.0.2", + "ampersand-events": "^2.0.2", + "ampersand-state": "^5.0.3", + "core-decorators": "^0.20.0", + "crypto-js": "^4.1.1", + "jsonwebtoken": "^9.0.0", + "lodash": "^4.17.21", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@webex/webex-core/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", + "integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "devOptional": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-cli-detector": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/agent-cli-detector/-/agent-cli-detector-0.1.2.tgz", + "integrity": "sha512-qdZ/9JFORtTKJNhT/IczMeEfEUbUU0K5umYeiIQHX+AjHs+Y9SXVzSgaYlpZeyNMrvuh2HpZiOTpvS57iPfBkQ==", + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "agent-cli-detector": "dist/cli.js" + }, + "engines": { + "node": ">=18.18" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/alea": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/alea/-/alea-0.0.9.tgz", + "integrity": "sha512-7GrAOnIHGlKtOmZm09dHL+n5tXlao4uBGeXUPRX+I5PAyZqa95CaSFC9bXpkFJpT6j5N3+UKoxDfPmmwBedg7A==", + "license": "MIT" + }, + "node_modules/ampersand-class-extend": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ampersand-class-extend/-/ampersand-class-extend-2.0.0.tgz", + "integrity": "sha512-i8hQvA4vZz9UfQAi0A4oBASYOZzlYgjFVkw0K1xpeKNSvq+KYkFOqJKkNvHCbbuKUNJnFk3kECSKPDAJ6ocEOg==", + "license": "MIT", + "dependencies": { + "lodash": "^4.11.1" + } + }, + "node_modules/ampersand-collection": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ampersand-collection/-/ampersand-collection-2.0.2.tgz", + "integrity": "sha512-IjDa4HTL/tdQDDL0SGyWk4AHD02iNtUSLRWkAsJ2biPvapljW9HNgIEIdbPnnR+7Gb9BJkjesaLNjVZfAMzeuA==", + "license": "MIT", + "dependencies": { + "ampersand-class-extend": "^2.0.0", + "ampersand-events": "^2.0.1", + "ampersand-version": "^1.0.2", + "lodash": "^4.11.1" + } + }, + "node_modules/ampersand-events": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ampersand-events/-/ampersand-events-2.0.2.tgz", + "integrity": "sha512-pPnVEJviRxXi9YhZA9j3GwGGBTlDLi+YIoBvrpKXgce+CO1nMlZU2aOV8OJogNuR2YPbptAUHNz7SKX+MvLj8A==", + "license": "MIT", + "dependencies": { + "ampersand-version": "^1.0.2", + "lodash": "^4.6.1" + } + }, + "node_modules/ampersand-state": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/ampersand-state/-/ampersand-state-5.0.3.tgz", + "integrity": "sha512-sr904K5zvw6mkGjFHhTcfBIdpoJ6mn/HrFg7OleRmBpw3apLb3Z0gVrgRTb7kK1wOLI34vs4S+IXqNHUeqWCzw==", + "license": "MIT", + "dependencies": { + "ampersand-events": "^2.0.1", + "ampersand-version": "^1.0.0", + "array-next": "~0.0.1", + "key-tree-store": "^1.3.0", + "lodash": "^4.12.0" + } + }, + "node_modules/ampersand-version": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ampersand-version/-/ampersand-version-1.0.2.tgz", + "integrity": "sha512-FVVLY7Pghtgc8pQl0rF3A3+OS/CZ+/ILLMIYIaO1cA9v5SRkainqUMfSot3fu32svuThIsYK3q9iCsH9W5+mWQ==", + "license": "MIT", + "dependencies": { + "find-root": "^0.1.1", + "through2": "^0.6.3" + } + }, + "node_modules/anser": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", + "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==", + "license": "MIT", + "optional": true, + "peer": true + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/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==", + "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "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", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "devOptional": true, + "license": "Python-2.0" + }, + "node_modules/array-next": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-next/-/array-next-0.0.1.tgz", + "integrity": "sha512-sBOC/Iaz2hCcYi2XlyRfyZCRUxamlE5NJXEFjE9BTx23HALnWAFsPjGtfrAclt9o3G/38Het2yyeyOd3CEY7lg==", + "license": "MIT" + }, + "node_modules/array-parallel": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/array-parallel/-/array-parallel-0.1.3.tgz", + "integrity": "sha512-TDPTwSWW5E4oiFiKmz6RGJ/a80Y91GuLgUYuLd49+XBS75tYo8PNgaT2K/OxuQYqkoI852MDGBorg9OcUSTQ8w==", + "license": "MIT" + }, + "node_modules/array-series": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/array-series/-/array-series-0.1.5.tgz", + "integrity": "sha512-L0XlBwfx9QetHOsbLDrE/vh2t018w9462HM3iaFfxRiK83aJjAt/Ja3NMkOW7FICwWTlQBa3ZbL5FKhuQWkDrg==", + "license": "MIT" + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/asmcrypto.js": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/asmcrypto.js/-/asmcrypto.js-0.22.0.tgz", + "integrity": "sha512-usgMoyXjMbx/ZPdzTSXExhMPur2FTdz/Vo5PVx2gIaBcdAAJNOFlsdgqveM8Cff7W0v+xrf9BwjOV26JSAF9qA==", + "license": "MIT" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-2.4.0.tgz", + "integrity": "sha512-PvZC0FMyMut8aOnR2jAEGSkmRtHIUYPe9amUEnGjr9TdnUmsfoOkjrvUkOEU9mzpYBR1HyO9bF+8U1cLTMMHhQ==", + "license": "BSD-3-Clause", + "dependencies": { + "pvutils": "^1.1.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "license": "MIT" + }, + "node_modules/b64-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/b64-lite/-/b64-lite-1.4.0.tgz", + "integrity": "sha512-aHe97M7DXt+dkpa8fHlCcm1CnskAHrJqEfMI0KN7dwqlzml/aUe1AGt6lk51HzrSfVD67xOso84sOpr+0wIe2w==", + "license": "MIT", + "dependencies": { + "base-64": "^0.1.0" + } + }, + "node_modules/b64u-lite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/b64u-lite/-/b64u-lite-1.1.0.tgz", + "integrity": "sha512-929qWGDVCRph7gQVTC6koHqQIpF4vtVaSbwLltFQo44B1bYUquALswZdBKFfrJCPEnsCOvWkJsPdQYZ/Ukhw8A==", + "license": "MIT", + "dependencies": { + "b64-lite": "^1.4.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-react-compiler": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz", + "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.26.0" + } + }, + "node_modules/babel-plugin-react-native-web": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.21.2.tgz", + "integrity": "sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/babel-plugin-syntax-hermes-parser": { + "version": "0.36.1", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.36.1.tgz", + "integrity": "sha512-ycduwJbvdvIMmVvlAZqGggS+pm5Eu4Bk9pcV9Sm2Z4PJNRVsKkv0g7vHj+LeuC1gHTeF67sJXFOq61IlqCa2hA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "hermes-parser": "0.36.1" + } + }, + "node_modules/babel-plugin-transform-flow-enums": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz", + "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/plugin-syntax-flow": "^7.12.1" + } + }, + "node_modules/babel-preset-expo": { + "version": "57.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-57.0.1.tgz", + "integrity": "sha512-ClW79dx27GJVwKf/YMKCrR18uer6jlREZtKVB00HQMIoyeM5Qxh9axKTT0GUNFkFq596wi216ovp1zcGMUhE8g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/generator": "^7.20.5", + "@babel/helper-module-imports": "^7.25.9", + "@babel/plugin-proposal-decorators": "^7.12.9", + "@babel/plugin-proposal-export-default-from": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-default-from": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.25.4", + "@babel/plugin-transform-class-static-block": "^7.27.1", + "@babel/plugin-transform-classes": "^7.25.4", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-flow-strip-types": "^7.25.2", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.28.6", + "@babel/plugin-transform-react-jsx-development": "^7.27.1", + "@babel/plugin-transform-react-pure-annotations": "^7.27.1", + "@babel/plugin-transform-runtime": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.25.2", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/preset-typescript": "^7.23.0", + "@react-native/babel-plugin-codegen": "0.86.0", + "babel-plugin-react-compiler": "^1.0.0", + "babel-plugin-react-native-web": "~0.21.0", + "babel-plugin-syntax-hermes-parser": "^0.36.0", + "babel-plugin-transform-flow-enums": "^0.0.2", + "debug": "^4.3.4" + }, + "peerDependencies": { + "@babel/runtime": "^7.20.0", + "expo": "*", + "expo-widgets": "^57.0.1", + "react-refresh": ">=0.14.0 <1.0.0" + }, + "peerDependenciesMeta": { + "@babel/runtime": { + "optional": true + }, + "expo": { + "optional": true + }, + "expo-widgets": { + "optional": true + } + } + }, + "node_modules/backoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", + "integrity": "sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==", + "license": "MIT", + "dependencies": { + "precond": "0.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base-64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", + "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "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/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.42", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.42.tgz", + "integrity": "sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "license": "Unlicense", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", + "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "license": "MIT", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "license": "MIT" + }, + "node_modules/bplist-creator": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz", + "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "stream-buffers": "2.2.x" + } + }, + "node_modules/bplist-parser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", + "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "optional": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.5.tgz", + "integrity": "sha512-Cu2E6QejHWzuDMTkuwgpABFgDfZrXLQq5V13YOACZx4mFAG4IwGTbTfHPMr4WtxlHoXSM8FIuRwYYCz5XiabaQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001800", + "electron-to-chromium": "^1.5.387", + "node-releases": "^2.0.50", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "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==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/bson": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", + "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/btoa": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", + "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", + "license": "(MIT OR Apache-2.0)", + "bin": { + "btoa": "bin/btoa.js" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bytestreamjs": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-1.1.3.tgz", + "integrity": "sha512-JDGoiJ+yt+4Ui1e/vMWx5TRvmnErBBbsOkprXgbe1fRp2XZzI8MoknoiR/ZVCya9aWJbOhrJ5Heon1wrAdftkg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001802", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001802.tgz", + "integrity": "sha512-vmv8ub2xwTNmljSKf82mtCk5JH7hC+YgzLj3P5zotvA0tPQ9016tdNNOG8WRca1IxOnhSsivB+J0z5FeE5LOUw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0", + "optional": true, + "peer": true + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "license": "Apache-2.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chrome-launcher": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", + "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0" + }, + "bin": { + "print-chrome-path": "bin/print-chrome-path.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/chromium-edge-launcher": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-0.3.0.tgz", + "integrity": "sha512-p03azHlGjtyRvFEee3cyvtsRYdniSkwjkzmM/KmVnqT5d7QkkwpJBhis/zCLMYdQMVJ5tt140TBNqqrZPaWeFA==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0", + "mkdirp": "^1.0.4" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true, + "license": "MIT" + }, + "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==", + "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", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "license": "MIT", + "optional": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/core-decorators": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/core-decorators/-/core-decorators-0.20.0.tgz", + "integrity": "sha512-7cp/Pz3AmQXjRwhAsFN+8ndRiBNyLxtZgC/fhKvrwQTf2ZlZma6LnimoJPrOqgxZ0tIeI9VvSs+QKe0OPJ0SuA==", + "license": "MIT" + }, + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "hasInstallScript": true, + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detectrtc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/detectrtc/-/detectrtc-1.4.1.tgz", + "integrity": "sha512-lxvyNN6/dSnwoVj1VstVFHel7S0BTmkfv1+01IBEy42D20pue27eB/MfphUOQz78jJ7WcQJDo6ZybhgBlUDi0Q==", + "license": "MIT" + }, + "node_modules/dnssd-advertise": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/dnssd-advertise/-/dnssd-advertise-1.1.6.tgz", + "integrity": "sha512-Ndrrf6BMPalkQPd/zubL+4YghH2J9NspapQ09uDXwYbvOPkP0oaqf5CkcwJ0b50kS2O3ul6yVu+jz+RY62Cejg==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/electron-to-chromium": { + "version": "1.5.387", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.387.tgz", + "integrity": "sha512-TaxwufTFDufvPEoXdhwVrA3UdFWBeWGkYoJ1K8ldF1xe6gKfth6iRNS5lTQ5JPNOHdGQm8PT1QYKUqFLCiUefQ==", + "license": "ISC", + "optional": true, + "peer": true + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", + "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exifr": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/exifr/-/exifr-5.0.6.tgz", + "integrity": "sha512-iDB4IhKoKVF+uDDrHRlyNxWqGaTxYluVWqvBWVG54HkQZe8qkFYl9eQrjEP3d8Q4UMBZ9rWu3Pa+mfC+o4CZuw==", + "license": "MIT" + }, + "node_modules/expo": { + "version": "57.0.2", + "resolved": "https://registry.npmjs.org/expo/-/expo-57.0.2.tgz", + "integrity": "sha512-QmyNQJNFJb/I6bQYpxl39jqyhCSlFXtiwBCyCFl3a7a18NZ8pHsVHTvLdRIXFI/bNXdCm/g7JMXoJB4eFKLBmg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.20.0", + "@expo/cli": "^57.0.4", + "@expo/config": "~57.0.2", + "@expo/config-plugins": "~57.0.2", + "@expo/devtools": "~57.0.0", + "@expo/dom-webview": "~57.0.0", + "@expo/fingerprint": "^0.20.2", + "@expo/local-build-cache-provider": "^57.0.2", + "@expo/log-box": "^57.0.0", + "@expo/metro": "~56.0.0", + "@expo/metro-config": "~57.0.3", + "@ungap/structured-clone": "^1.3.0", + "babel-preset-expo": "~57.0.1", + "expo-asset": "~57.0.3", + "expo-constants": "~57.0.3", + "expo-file-system": "~57.0.0", + "expo-font": "~57.0.0", + "expo-keep-awake": "~57.0.0", + "expo-modules-autolinking": "~57.0.4", + "expo-modules-core": "~57.0.2", + "pretty-format": "^29.7.0", + "react-refresh": "^0.14.2", + "whatwg-url-minimum": "^0.1.2" + }, + "bin": { + "expo": "bin/cli", + "expo-modules-autolinking": "bin/autolinking", + "fingerprint": "bin/fingerprint" + }, + "peerDependencies": { + "@expo/dom-webview": "*", + "@expo/metro-runtime": "*", + "react": "*", + "react-dom": "*", + "react-native": "*", + "react-native-web": "*", + "react-native-webview": "*" + }, + "peerDependenciesMeta": { + "@expo/dom-webview": { + "optional": true + }, + "@expo/metro-runtime": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native-web": { + "optional": true + }, + "react-native-webview": { + "optional": true + } + } + }, + "node_modules/expo-asset": { + "version": "57.0.3", + "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-57.0.3.tgz", + "integrity": "sha512-6E08JDuYrktY5pKNn2WiFBPBfj6bvFb++ccuBTijK8BUk/afSoy6n35h583LmC2YHgHTepWHHWNfr61nYcMd8Q==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/image-utils": "^0.11.1", + "expo-constants": "~57.0.3" + }, + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo-constants": { + "version": "57.0.3", + "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-57.0.3.tgz", + "integrity": "sha512-BghbZlzwFnA22BG0CWv6W29zx8w19FozYPfSeZ3HjMitoy4aAmF1FnFbbjYSmZz6HHXXTWOfqwobOEIaglfzxg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/env": "~2.4.1" + }, + "peerDependencies": { + "expo": "*", + "react-native": "*" + } + }, + "node_modules/expo-file-system": { + "version": "57.0.0", + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-57.0.0.tgz", + "integrity": "sha512-G+eytNuNGMiS7dbdj1j0nAYMowXnNr1vpO+jss6nQvBlRxshcGBFMtk8xfc67ynz0MUVkzod7WwKO7Vf1iOaJw==", + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "expo": "*", + "react-native": "*" + } + }, + "node_modules/expo-font": { + "version": "57.0.0", + "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-57.0.0.tgz", + "integrity": "sha512-zF+J7WrNFjqyAADwdvDgkFEoIQv9DqcjJ57HVstNEH7/7Tx1ThPEhKraodEQOwSjMYWirP+4BYsVbdb+/Zr4QQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "fontfaceobserver": "^2.1.0" + }, + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo-keep-awake": { + "version": "57.0.0", + "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-57.0.0.tgz", + "integrity": "sha512-WqEoyDNSmUeAI9Gu7UaWKDjOhfaV+jGcms7N0hh/EAr7sqJrI2s0HpLSC3P9cWfXFUZCL1zZjd22m/NbsJYCKg==", + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "expo": "*", + "react": "*" + } + }, + "node_modules/expo-modules-autolinking": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-0.3.4.tgz", + "integrity": "sha512-Mu3CIMqEAI8aNM18U/l+7CCi+afU8dERrKjDDEx/Hu7XX3v3FcnnP+NuWDLY/e9/ETzwTJaqoRoBuzhawsuLWw==", + "license": "MIT", + "optional": true, + "dependencies": { + "chalk": "^4.1.0", + "commander": "^7.2.0", + "fast-glob": "^3.2.5", + "find-up": "~5.0.0", + "fs-extra": "^9.1.0" + }, + "bin": { + "expo-modules-autolinking": "bin/expo-modules-autolinking.js" + } + }, + "node_modules/expo-modules-core": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-0.4.10.tgz", + "integrity": "sha512-uCZA3QzF0syRaHwYY99iaNhnye4vSQGsJ/y6IAiesXdbeVahWibX4G1KoKNPUyNsKXIM4tqA+4yByUSvJe4AAw==", + "license": "MIT", + "optional": true, + "dependencies": { + "compare-versions": "^3.4.0", + "invariant": "^2.2.4" + } + }, + "node_modules/expo-modules-jsi": { + "version": "57.0.0", + "resolved": "https://registry.npmjs.org/expo-modules-jsi/-/expo-modules-jsi-57.0.0.tgz", + "integrity": "sha512-lNcA2XLKpbG/Qr3CZ6yCgzlK8oT+zwuD19QKYoRfN5ZurkVhnSA3QdTR5K32n9AxohcENYtZRtnHr2pZoG7W4w==", + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "react-native": "*" + } + }, + "node_modules/expo-random": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/expo-random/-/expo-random-14.0.1.tgz", + "integrity": "sha512-gX2mtR9o+WelX21YizXUCD/y+a4ZL+RDthDmFkHxaYbdzjSYTn8u/igoje/l3WEO+/RYspmqUFa8w/ckNbt6Vg==", + "deprecated": "This package is now deprecated in favor of expo-crypto, which provides the same functionality. To migrate, replace all imports from expo-random with imports from expo-crypto.", + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.0" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-server": { + "version": "57.0.0", + "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-57.0.0.tgz", + "integrity": "sha512-18byjwFbHVFrGzI4IH1o2MZiiYwvO/y3d+JL3sq50Lg3Id1titwIRMh1fjbHbpM+wP6x14KJY0Ers1UYsjGq8Q==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=20.16.0" + } + }, + "node_modules/expo/node_modules/expo-modules-autolinking": { + "version": "57.0.4", + "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-57.0.4.tgz", + "integrity": "sha512-O0G2WRw4xtPpuhwufo2HQ6fyVQhNxtUVmO+tJD3+dB3bIslQCz3pM+s8ouhkf7ZU97g/wZOrd33umuHbbZjM3g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/require-utils": "^57.0.1", + "@expo/spawn-async": "^1.8.0", + "chalk": "^4.1.0", + "commander": "^7.2.0" + }, + "bin": { + "expo-modules-autolinking": "bin/expo-modules-autolinking.js" + } + }, + "node_modules/expo/node_modules/expo-modules-core": { + "version": "57.0.2", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-57.0.2.tgz", + "integrity": "sha512-gs1Ng2Ci1C/CwN1xRZp2RR74C9iWByf9AHaovYEtOlkly9AolitQGAt9+iLT0CoCb6xw128NcDQ00OJl/Bmv9Q==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@expo/expo-modules-macros-plugin": "0.3.0", + "expo-modules-jsi": "~57.0.0", + "invariant": "^2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*", + "react-native-worklets": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0" + }, + "peerDependenciesMeta": { + "react-native-worklets": { + "optional": true + } + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "license": "Apache-2.0", + "optional": true, + "peer": true + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "optional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "license": "ISC", + "optional": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-dotslash": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/fb-dotslash/-/fb-dotslash-0.5.8.tgz", + "integrity": "sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA==", + "license": "(MIT OR Apache-2.0)", + "optional": true, + "peer": true, + "bin": { + "dotslash": "bin/dotslash" + }, + "engines": { + "node": ">=20" + } + }, + "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==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fetch-nodeshim": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/fetch-nodeshim/-/fetch-nodeshim-0.4.10.tgz", + "integrity": "sha512-m6I8ALe4L4XpdETy7MJZWs6L1IVMbjs99bwbpIKphxX+0CTns4IKDWJY0LWfr4YsFjfg+z1TjzTMU8lKl8rG0w==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "license": "MIT", + "dependencies": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "optional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/find-root": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-0.1.2.tgz", + "integrity": "sha512-GyDxVgA61TZcrgDJPqOqGBpi80Uf2yIstubgizi7AjC9yPdRrqBR+Y0MvK4kXnYlaoz3d+SGxDHMYVkwI/yd2w==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/flow-enums-runtime": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz", + "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/fontfaceobserver": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz", + "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==", + "license": "BSD-2-Clause", + "optional": true, + "peer": true + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "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==", + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/getenv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/getenv/-/getenv-2.0.0.tgz", + "integrity": "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", + "optional": true, + "peer": true, + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "license": "BlueOak-1.0.0", + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "license": "MIT", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gm": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/gm/-/gm-1.25.1.tgz", + "integrity": "sha512-jgcs2vKir9hFogGhXIfs0ODhJTfIrbECCehg38tqFgHm8zqXx7kAJyCYAFK4jTjx71AxrkFtkJBawbAxYUPX9A==", + "deprecated": "The gm module has been sunset. Please migrate to an alternative. https://github.com/aheckmann/gm?tab=readme-ov-file#2025-02-24-this-project-is-not-maintained", + "license": "MIT", + "dependencies": { + "array-parallel": "~0.1.3", + "array-series": "~0.1.5", + "cross-spawn": "^7.0.5", + "debug": "^3.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gm/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC", + "optional": true + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hermes-compiler": { + "version": "250829098.0.14", + "resolved": "https://registry.npmjs.org/hermes-compiler/-/hermes-compiler-250829098.0.14.tgz", + "integrity": "sha512-5meXwsZxgiqFaJjNzwjzI9IyUkuGGBisu+z9BvQWmGVpjH6nz11hgqkyxe4dl8UAdyIV4lTbz91+Dlnjz0VxqA==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/hermes-estree": { + "version": "0.36.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.36.1.tgz", + "integrity": "sha512-guv1nQ6IJ7S83NRFPWc3SA7IBZrdNC9kapwOq6uXvF4wP+sDCgjzQbKPCoyYmoyZRzztF/n/c36l/rccCZSiCw==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/hermes-parser": { + "version": "0.36.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.36.1.tgz", + "integrity": "sha512-GApNk4zLHi2UWoWZZkx7LNCOSzLSc5lB55pZ/PhK7ycFeg7u5LcF88p/WbpIi1XUDtE0MpHE3uRR3u3KB7TjSQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "hermes-estree": "0.36.1" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz", + "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "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", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "optional": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ip-anonymize": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ip-anonymize/-/ip-anonymize-0.1.0.tgz", + "integrity": "sha512-cZJu+N5JKKFGMK0eEQWNaQMn2EhCysciVM6eotCJwfqotj16BTfVchKsJCH6mQAT9N0GC7oWRcsZ6Lb8dDiwTA==", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "license": "MIT" + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isomorphic-webcrypto": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/isomorphic-webcrypto/-/isomorphic-webcrypto-2.3.8.tgz", + "integrity": "sha512-XddQSI0WYlSCjxtm1AI8kWQOulf7hAN3k3DclF1sxDJZqOe0pcsOt675zvWW91cZH9hYs3nlA3Ev8QK5i80SxQ==", + "license": "MIT", + "dependencies": { + "@peculiar/webcrypto": "^1.0.22", + "asmcrypto.js": "^0.22.0", + "b64-lite": "^1.3.1", + "b64u-lite": "^1.0.1", + "msrcrypto": "^1.5.6", + "str2buf": "^1.3.0", + "webcrypto-shim": "^0.1.4" + }, + "optionalDependencies": { + "@unimodules/core": "*", + "@unimodules/react-native-adapter": "*", + "expo-random": "*", + "react-native-securerandom": "^0.1.1" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "license": "MIT" + }, + "node_modules/javascript-state-machine": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/javascript-state-machine/-/javascript-state-machine-3.1.0.tgz", + "integrity": "sha512-BwhYxQ1OPenBPXC735RgfB+ZUG8H3kjsx8hrYTgWnoy6TPipEy4fiicyhT2lxRKAXq9pG7CfFT8a2HLr6Hmwxg==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jimp-compact": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz", + "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT", + "optional": true + }, + "node_modules/js-yaml": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "devOptional": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "license": "MIT" + }, + "node_modules/jsc-safe-url": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz", + "integrity": "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==", + "license": "0BSD", + "optional": true, + "peer": true + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/key-tree-store": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/key-tree-store/-/key-tree-store-1.3.0.tgz", + "integrity": "sha512-qXk+lR+LXvGos3wqMxIMWweKDgCx8ZKWM6BEPm7iZkOKug5ggi66vUt+3vbtKJLBrAyOxQ4S8JRwK++Q4XZRmw==", + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lan-network": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/lan-network/-/lan-network-0.2.1.tgz", + "integrity": "sha512-ONPnazC96VKDntab9j9JKwIWhZ4ZUceB4A9Epu4Ssg0hYFmtHZSeQ+n15nIwTFmcBUKtExOer8WTJ4GF9MO64A==", + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "lan-network": "dist/lan-network-cli.js" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lighthouse-logger": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", + "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^2.6.9", + "marky": "^1.2.2" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "license": "MPL-2.0", + "optional": true, + "peer": true, + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash._arraycopy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", + "integrity": "sha512-RHShTDnPKP7aWxlvXKiDT6IX2jCs6YZLCtNhOru/OX2Q/tzX295vVBK5oX1ECtN+2r86S0Ogy8ykP1sgCZAN0A==", + "license": "MIT" + }, + "node_modules/lodash._arrayeach": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz", + "integrity": "sha512-Mn7HidOVcl3mkQtbPsuKR0Fj0N6Q6DQB77CtYncZcJc0bx5qv2q4Gl6a0LC1AN+GSxpnBDNnK3CKEm9XNA4zqQ==", + "license": "MIT" + }, + "node_modules/lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha512-t3N26QR2IdSN+gqSy9Ds9pBu/J1EAFEshKlUHpJG3rvyJOYgcELIxcIeKKfZk7sjOz11cFfzJRsyFry/JyabJQ==", + "license": "MIT", + "dependencies": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash._baseclone": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz", + "integrity": "sha512-1K0dntf2dFQ5my0WoGKkduewR6+pTNaqX03kvs45y7G5bzl4B3kTR4hDfJIc2aCQDeLyQHhS280tc814m1QC1Q==", + "license": "MIT", + "dependencies": { + "lodash._arraycopy": "^3.0.0", + "lodash._arrayeach": "^3.0.0", + "lodash._baseassign": "^3.0.0", + "lodash._basefor": "^3.0.0", + "lodash.isarray": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha512-rFR6Vpm4HeCK1WPGvjZSJ+7yik8d8PVUdCJx5rT2pogG4Ve/2ZS7kfmO5l5T2o5V2mqlNIfSF5MZlr1+xOoYQQ==", + "license": "MIT" + }, + "node_modules/lodash._basefor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz", + "integrity": "sha512-6bc3b8grkpMgDcVJv9JYZAk/mHgcqMljzm7OsbmcE2FGUMmmLQTPHlh/dFqR8LA0GQ7z4K67JSotVKu5058v1A==", + "license": "MIT" + }, + "node_modules/lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ==", + "license": "MIT" + }, + "node_modules/lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==", + "license": "MIT" + }, + "node_modules/lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha512-De+ZbrMu6eThFti/CSzhRvTKMgQToLxbij58LMfM8JnYDNSOjkjTCIaa8ixglOeGh2nyPlakbt5bJWJ7gvpYlQ==", + "license": "MIT" + }, + "node_modules/lodash.clone": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-3.0.3.tgz", + "integrity": "sha512-yVYPpFTdZDCLG2p07gVRTvcwN5X04oj2hu4gG6r0fer58JA08wAVxXzWM+CmmxO2bzOH8u8BkZTZqgX6juVF7A==", + "deprecated": "This package is deprecated. Use structuredClone instead.", + "license": "MIT", + "dependencies": { + "lodash._baseclone": "^3.0.0", + "lodash._bindcallback": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "node_modules/lodash.clonedeep": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-3.0.2.tgz", + "integrity": "sha512-I8MpGh5z+6OixDAAb21teLSZDmqVPjlq02Q7ZFrbn2xnQHYYuJf6on/94SWpF/p0s3p/cEv/53ro4AhDOfCR0g==", + "license": "MIT", + "dependencies": { + "lodash._baseclone": "^3.0.0", + "lodash._bindcallback": "^3.0.0" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "license": "MIT" + }, + "node_modules/lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==", + "license": "MIT", + "dependencies": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/log-symbols/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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/log-symbols/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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/log-symbols/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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/marky": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz", + "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==", + "license": "Apache-2.0", + "optional": true, + "peer": true + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT", + "optional": true + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/metro": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.84.4.tgz", + "integrity": "sha512-8ETTubqfD6ornDy2zYDvRcKnVDOXdFJsjetYDBsY4oAsb6NJkiwFR+FaMESyGppFmQUyBQA4H4sFGxzcQSGtFA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/core": "^7.25.2", + "@babel/generator": "^7.29.1", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "accepts": "^2.0.0", + "ci-info": "^2.0.0", + "connect": "^3.6.5", + "debug": "^4.4.0", + "error-stack-parser": "^2.0.6", + "flow-enums-runtime": "^0.0.6", + "graceful-fs": "^4.2.4", + "hermes-parser": "0.35.0", + "image-size": "^1.0.2", + "invariant": "^2.2.4", + "jest-worker": "^29.7.0", + "jsc-safe-url": "^0.2.2", + "lodash.throttle": "^4.1.1", + "metro-babel-transformer": "0.84.4", + "metro-cache": "0.84.4", + "metro-cache-key": "0.84.4", + "metro-config": "0.84.4", + "metro-core": "0.84.4", + "metro-file-map": "0.84.4", + "metro-resolver": "0.84.4", + "metro-runtime": "0.84.4", + "metro-source-map": "0.84.4", + "metro-symbolicate": "0.84.4", + "metro-transform-plugins": "0.84.4", + "metro-transform-worker": "0.84.4", + "mime-types": "^3.0.1", + "nullthrows": "^1.1.1", + "serialize-error": "^2.1.0", + "source-map": "^0.5.6", + "throat": "^5.0.0", + "ws": "^7.5.10", + "yargs": "^17.6.2" + }, + "bin": { + "metro": "src/cli.js" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-babel-transformer": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.84.4.tgz", + "integrity": "sha512-rvCfz8snl9h20VcvpOHxZuHP1SlAkv4HXbzw7nyyVwu6Eqo5PRerbakQ9XmUCOsRy70spJ37O+G1TK8oMzo48g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.25.2", + "flow-enums-runtime": "^0.0.6", + "hermes-parser": "0.35.0", + "metro-cache-key": "0.84.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-babel-transformer/node_modules/hermes-estree": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.35.0.tgz", + "integrity": "sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/metro-babel-transformer/node_modules/hermes-parser": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.35.0.tgz", + "integrity": "sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "hermes-estree": "0.35.0" + } + }, + "node_modules/metro-cache": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.84.4.tgz", + "integrity": "sha512-gpcFQdSLUwUCk71saKoE64jLFbx2nwTfVCcPSULMNT8QYq0p1eZZE29Jvd0HtT/UlhC3ZOutLxJME5xqD2JUZg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "exponential-backoff": "^3.1.1", + "flow-enums-runtime": "^0.0.6", + "https-proxy-agent": "^7.0.5", + "metro-core": "0.84.4" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-cache-key": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.84.4.tgz", + "integrity": "sha512-wVO79aGrkYImpnaVS4+d5RrRBRPX31QtvKB3wKGBuiNSznduZTQHzsrJZRroFJSwnygrzdsGUtDQPuqqFjFdvw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-cache/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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/metro-cache/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/metro-config": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.84.4.tgz", + "integrity": "sha512-PMotGDjXcXLWo2TMRH+VR99phFNgYTwqh4OoieIKK3yTJa1Jmkl+fZJxDO0jfBvNF+WESHciHvpNuBtXaF3B0Q==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "connect": "^3.6.5", + "flow-enums-runtime": "^0.0.6", + "jest-validate": "^29.7.0", + "metro": "0.84.4", + "metro-cache": "0.84.4", + "metro-core": "0.84.4", + "metro-runtime": "0.84.4", + "yaml": "^2.6.1" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-core": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.84.4.tgz", + "integrity": "sha512-HONpWC5LGXZn3ffkd4Hu6AIrfE7j4Z0g0wMo/goV24WOB3lhuFZ40KgvaDiSw8iyQHloMYay5N/wPX+z8oN/PQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "lodash.throttle": "^4.1.1", + "metro-resolver": "0.84.4" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-file-map": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.84.4.tgz", + "integrity": "sha512-KSVDi/u60hKPx++NLu3MTIvyjzNoJnFAF8PQFxaj1jiSka/wjw+Ua6sNuJ0TDHQv+7AAoFQxeMgaRAe8Yic5wQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.4.0", + "fb-watchman": "^2.0.0", + "flow-enums-runtime": "^0.0.6", + "graceful-fs": "^4.2.4", + "invariant": "^2.2.4", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "nullthrows": "^1.1.1", + "walker": "^1.0.7" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-minify-terser": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.84.4.tgz", + "integrity": "sha512-5qpbaVOMC7CPitIpuewzVeGw7E+C3ykbv2mqTjQLl85Z3annSVGlSCTcsZjqXZzjupfK4Ztj3dDc4kc44NZwtQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "terser": "^5.15.0" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-resolver": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.84.4.tgz", + "integrity": "sha512-1qLgbxQ5ZGhhutuPot1Yp348ofDsATL2WkrHF65TobqTT9K3P9qJXw38bomk7ncp5B7OYMfWwtyBZo1lCV792A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-runtime": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.84.4.tgz", + "integrity": "sha512-Jibypds4g7AhzdRKY+kDoj51s5EXMwgyp5ddtlreDAsWefMdOx+agWqgm0H2XSZ/ueanHHVM89fnf5OJnlxa8Q==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.25.0", + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-source-map": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.84.4.tgz", + "integrity": "sha512-jbWkPxIesVuo1IWkvezmMJld6iu8nD62GsrZiV6jP37AOdbo4OBq1FJ+qkOg8sV05wAHB//jAbziuW0SlJfW4g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "flow-enums-runtime": "^0.0.6", + "invariant": "^2.2.4", + "metro-symbolicate": "0.84.4", + "nullthrows": "^1.1.1", + "ob1": "0.84.4", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-symbolicate": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.84.4.tgz", + "integrity": "sha512-OnfpacxUqGPZQ27t8qK9mFa7uqHIlVWeqRqkCbvMvreEBiamEeOn8krKtcwgP5M4cYDPwuSmCTopHMVthqG4zA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "invariant": "^2.2.4", + "metro-source-map": "0.84.4", + "nullthrows": "^1.1.1", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + }, + "bin": { + "metro-symbolicate": "src/index.js" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-transform-plugins": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.84.4.tgz", + "integrity": "sha512-kehr6HbAecqD0/a3xLXobELdPaAmRAl8bel0qagPF4vhZtux93nS8S4eq2kgKt6J2GnQpVjSoW1PXdst04mwow==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/generator": "^7.29.1", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "flow-enums-runtime": "^0.0.6", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro-transform-worker": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.84.4.tgz", + "integrity": "sha512-W1IYMvvXTu4MxYr7d9h7CeG2vpIr3bmLLIavkPY4O1ilzDrvS8z/NEe6y+pC44Ff7raMXQgYSfdqDUwN/i39gg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/generator": "^7.29.1", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "flow-enums-runtime": "^0.0.6", + "metro": "0.84.4", + "metro-babel-transformer": "0.84.4", + "metro-cache": "0.84.4", + "metro-cache-key": "0.84.4", + "metro-minify-terser": "0.84.4", + "metro-source-map": "0.84.4", + "metro-transform-plugins": "0.84.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/metro/node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/metro/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/metro/node_modules/hermes-estree": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.35.0.tgz", + "integrity": "sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/metro/node_modules/hermes-parser": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.35.0.tgz", + "integrity": "sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "hermes-estree": "0.35.0" + } + }, + "node_modules/metro/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/metro/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/metro/node_modules/ws": { + "version": "7.5.11", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", + "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==", + "license": "MIT", + "optional": true, + "peer": true, + "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/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "optional": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types/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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/min-document": { + "version": "2.19.2", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.2.tgz", + "integrity": "sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==", + "license": "MIT", + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "optional": true, + "peer": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/mongodb": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.4.tgz", + "integrity": "sha512-K5q8aBqEXMwWdVNh94UQTwZ6BejVbFhh1uB6c5FKtPE9eUMZPUO3sRZdgIEcHSrAWmxzpG/FeODDKL388sqRmw==", + "license": "Apache-2.0", + "dependencies": { + "bl": "^2.2.1", + "bson": "^1.1.4", + "denque": "^1.4.1", + "optional-require": "^1.1.8", + "safe-buffer": "^5.1.2" + }, + "engines": { + "node": ">=4" + }, + "optionalDependencies": { + "saslprep": "^1.0.0" + }, + "peerDependenciesMeta": { + "aws4": { + "optional": true + }, + "bson-ext": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "mongodb-extjson": { + "optional": true + }, + "snappy": { + "optional": true + } + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/msrcrypto": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/msrcrypto/-/msrcrypto-1.5.8.tgz", + "integrity": "sha512-ujZ0TRuozHKKm6eGbKHfXef7f+esIhEckmThVnz7RNyiOJd7a6MXj2JGBoL9cnPDW+JMG16MoTUh5X+XXjI66Q==", + "license": "Apache-2.0" + }, + "node_modules/multitars": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/multitars/-/multitars-1.0.0.tgz", + "integrity": "sha512-H/J4fMLedtudftaYMOg7ajzLYgT3/rwbWVJbqr/iUgB8DQztn38ys5HOqI1CzSxx8QhXXwOOnnBvd4v3jG5+Mg==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/nanoid": { + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-cron": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz", + "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==", + "license": "ISC", + "dependencies": { + "uuid": "8.3.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/node-forge": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/node-jose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-2.2.0.tgz", + "integrity": "sha512-XPCvJRr94SjLrSIm4pbYHKLEaOsDvJCpyFw/6V/KK/IXmyZ6SFBzAUDO9HQf4DB/nTEFcRGH87mNciOP23kFjw==", + "license": "Apache-2.0", + "dependencies": { + "base64url": "^3.0.1", + "buffer": "^6.0.3", + "es6-promise": "^4.2.8", + "lodash": "^4.17.21", + "long": "^5.2.0", + "node-forge": "^1.2.1", + "pako": "^2.0.4", + "process": "^0.11.10", + "uuid": "^9.0.0" + } + }, + "node_modules/node-jose/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/node-kms": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/node-kms/-/node-kms-0.4.1.tgz", + "integrity": "sha512-qhrfrsEPooJCTDPc8yPaLIu8rHGKrSngK/X9eZziM0RUnMY3PtKU8PHmG5JokeNw7wokW8/dKtwEH5I24oW5ew==", + "license": "Apache-2.0", + "dependencies": { + "es6-promise": "^2.0.1", + "lodash.clone": "^3.0.2", + "lodash.clonedeep": "^3.0.1", + "node-jose": "^2.2.0", + "uuid": "^2.0.1" + } + }, + "node_modules/node-kms/node_modules/es6-promise": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz", + "integrity": "sha512-oyOjMhyKMLEjOOtvkwg0G4pAzLQ9WdbbeX7WdqKzvYXu+UFgD0Zo/Brq5Q49zNmnGPPzV5rmYvrr0jz1zWx8Iw==", + "license": "MIT" + }, + "node_modules/node-kms/node_modules/uuid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha512-FULf7fayPdpASncVy4DLh3xydlXEJJpvIELjYjNeQWYUZ9pclcpvCZSr2gkmN2FrrGcI7G/cJsIEwk5/8vfXpg==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT" + }, + "node_modules/node-random-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/node-random-name/-/node-random-name-1.0.1.tgz", + "integrity": "sha512-7+IpyBRtbHvTWXjdZxjxyaafdggIvA3IpNf2W3ZRe+ok3UyE32Qb8PCb4fKKPdZCCjoAk358yQZWywAimw8KCw==", + "license": "MIT", + "dependencies": { + "alea": "0.0.9" + } + }, + "node_modules/node-releases": { + "version": "2.0.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz", + "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-scr": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/node-scr/-/node-scr-0.3.0.tgz", + "integrity": "sha512-Hb0ykojynSbt7ra6eml6NX39WAumFfU3G81XvLpp2H7y8KjQc29oEIf2TlgZQCfA+pyxbY5t4a1xBqPpyrbpvw==", + "license": "Apache-2.0", + "dependencies": { + "es6-promise": "^2.0.1", + "lodash.clone": "^3.0.2", + "node-jose": "^2.0.0" + } + }, + "node_modules/node-scr/node_modules/es6-promise": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz", + "integrity": "sha512-oyOjMhyKMLEjOOtvkwg0G4pAzLQ9WdbbeX7WdqKzvYXu+UFgD0Zo/Brq5Q49zNmnGPPzV5rmYvrr0jz1zWx8Iw==", + "license": "MIT" + }, + "node_modules/npm-package-arg": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", + "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/ob1": { + "version": "0.84.4", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.84.4.tgz", + "integrity": "sha512-eJXMpz4aQHXF/YBB9ddqZDIS+ooO91hObo9FoW/xBkr54/zCwYYCDqT/O54vNo8kOkWs5Ou/y28NgdrV0edQNA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optional-require": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.10.tgz", + "integrity": "sha512-0r3OB9EIQsP+a5HVATHq2ExIy2q/Vaffoo4IAikW1spCYswhLxqWQS0i3GwS3AdY/OIP4SWZHLGz8CMU558PGw==", + "license": "Apache-2.0", + "dependencies": { + "require-at": "^1.0.6" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", + "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^2.0.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ora/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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/ora/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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ora/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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.2.0.tgz", + "integrity": "sha512-zJq6RP/5q+TO2OpFV3FHzlPnFjmkb7Nc99a5SNjJE+uu/PkpChs+NIZSSzbBoD+6kjiISXjfYdwj1ZRQ81dz/w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "(MIT AND Zlib)" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-headers": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.6.tgz", + "integrity": "sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==", + "license": "MIT" + }, + "node_modules/parse-png": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-png/-/parse-png-2.1.0.tgz", + "integrity": "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "pngjs": "^3.3.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", + "optional": true, + "peer": true, + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", + "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", + "license": "BlueOak-1.0.0", + "optional": true, + "peer": true, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkijs": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-2.4.0.tgz", + "integrity": "sha512-cjJP/mYuGyMrjJ49jI04khId5Oufd3nFTUYBzQTIIVNI7/oAWdwXEfpwTF8HELFV/gz+WGYUBHCe3KHWD8rYvg==", + "license": "BSD-3-Clause", + "dependencies": { + "asn1js": "^3.0.3", + "bytestreamjs": "^1.0.29", + "pvutils": "^1.1.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pkijs/node_modules/asn1js": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", + "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==", + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.5", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/plist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.1.tgz", + "integrity": "sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@xmldom/xmldom": "^0.9.10", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/plist/node_modules/@xmldom/xmldom": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz", + "integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.6" + } + }, + "node_modules/pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss": { + "version": "8.5.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", + "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/precond": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", + "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.4.tgz", + "integrity": "sha512-yWG/o/4oJfo036EKAfK6ACAoDOfHeRHx4tuxkfBZiauURiaSmYwlpOr5LQqKtIkRD2z1PLteme2WoxEnj4tHTg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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/pretty-format/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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pvtsutils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", + "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.5.tgz", + "integrity": "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/qs": { + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "license": "BSD-3-Clause", + "dependencies": { + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "~2.0.3" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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", + "optional": true + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-devtools-core": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.5.tgz", + "integrity": "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "shell-quote": "^1.6.1", + "ws": "^7" + } + }, + "node_modules/react-devtools-core/node_modules/ws": { + "version": "7.5.11", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", + "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==", + "license": "MIT", + "optional": true, + "peer": true, + "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/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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/react-native": { + "version": "0.86.0", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.86.0.tgz", + "integrity": "sha512-17ALh/dd6AO4pgOVmOO5Axll5PbErEo3XFyLokyzW6usyi+OShIEPwUW26wLPlhVifgSOIfECCH0WN+0IqtJ1w==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@react-native/assets-registry": "0.86.0", + "@react-native/codegen": "0.86.0", + "@react-native/community-cli-plugin": "0.86.0", + "@react-native/gradle-plugin": "0.86.0", + "@react-native/js-polyfills": "0.86.0", + "@react-native/normalize-colors": "0.86.0", + "@react-native/virtualized-lists": "0.86.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "ansi-regex": "^5.0.0", + "babel-plugin-syntax-hermes-parser": "0.36.0", + "base64-js": "^1.5.1", + "commander": "^12.0.0", + "flow-enums-runtime": "^0.0.6", + "hermes-compiler": "250829098.0.14", + "invariant": "^2.2.4", + "memoize-one": "^5.0.0", + "metro-runtime": "^0.84.3", + "metro-source-map": "^0.84.3", + "nullthrows": "^1.1.1", + "pretty-format": "^29.7.0", + "promise": "^8.3.0", + "react-devtools-core": "^6.1.5", + "react-refresh": "^0.14.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "0.27.0", + "semver": "^7.1.3", + "stacktrace-parser": "^0.1.10", + "tinyglobby": "^0.2.15", + "whatwg-fetch": "^3.0.0", + "ws": "^7.5.10", + "yargs": "^17.6.2" + }, + "bin": { + "react-native": "cli.js" + }, + "engines": { + "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0" + }, + "peerDependencies": { + "@react-native/jest-preset": "0.86.0", + "@types/react": "^19.1.1", + "react": "^19.2.3" + }, + "peerDependenciesMeta": { + "@react-native/jest-preset": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-native-securerandom": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/react-native-securerandom/-/react-native-securerandom-0.1.1.tgz", + "integrity": "sha512-CozcCx0lpBLevxiXEb86kwLRalBCHNjiGPlw3P7Fi27U6ZLdfjOCNRHD1LtBKcvPvI3TvkBXB3GOtLvqaYJLGw==", + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "*" + }, + "peerDependencies": { + "react-native": "*" + } + }, + "node_modules/react-native/node_modules/babel-plugin-syntax-hermes-parser": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.36.0.tgz", + "integrity": "sha512-LhD0xdoedDw7ansQgXbB2DADLZIK/LRXuWNBPuVzMc5S2WK5GyT89tCM+cQzxFGO0mGyLK6D5TrVOJJzAoDy8Q==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "hermes-parser": "0.36.0" + } + }, + "node_modules/react-native/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/react-native/node_modules/hermes-estree": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.36.0.tgz", + "integrity": "sha512-A1+8zn5oss2CFP7pKsOaxorQG6FNIz1WU1VDqruLPPZl3LVgeE2C5xfFg8Ow6/Ow4mSslLLtYP1J3n38eKyW9w==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/react-native/node_modules/hermes-parser": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.36.0.tgz", + "integrity": "sha512-GdpwMmH5x6IpC1cijvcvYnlPB60Mh6kTSF/NFdYV/j56gYdi+0RIakYs+eqOV+bbO0SW7mgVVGSsTJxyPQfo3w==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "hermes-estree": "0.36.0" + } + }, + "node_modules/react-native/node_modules/ws": { + "version": "7.5.11", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", + "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==", + "license": "MIT", + "optional": true, + "peer": true, + "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/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", + "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", + "license": "MIT", + "dependencies": { + "readable-stream": "^4.7.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readable-web-to-node-stream/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==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT" + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/regjsparser": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.2.tgz", + "integrity": "sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==", + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.5.tgz", + "integrity": "sha512-mzR4sElr1bfCaPJe7m8ilJ6ZXdDaGoObcYR0ZHSsktM/Lt21MVHj5De30GQH2eiZ1qGRTO7LCAzQsUeXTNexWQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-at": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", + "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==", + "license": "Apache-2.0", + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-workspace-root": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/resolve-workspace-root/-/resolve-workspace-root-2.0.1.tgz", + "integrity": "sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w==", + "license": "MIT", + "optional": true, + "peer": true + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "optional": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rtcpeerconnection-shim": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz", + "integrity": "sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==", + "license": "BSD-3-Clause", + "dependencies": { + "sdp": "^2.6.0" + }, + "engines": { + "node": ">=6.0.0", + "npm": ">=3.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "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", + "optional": true, + "dependencies": { + "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==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "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==", + "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/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "license": "MIT", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "license": "BlueOak-1.0.0", + "optional": true, + "peer": true, + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/sdp": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz", + "integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw==", + "license": "MIT" + }, + "node_modules/sdp-transform": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.15.0.tgz", + "integrity": "sha512-KrOH82c/W+GYQ0LHqtr3caRpM3ITglq3ljGUIb8LTki7ByacJZ9z+piSGiwZDsRyhQbYBOBJgr2k6X4BZXi3Kw==", + "license": "MIT", + "bin": { + "sdp-verify": "checker.js" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/send/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.9.0.tgz", + "integrity": "sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/simple-plist": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz", + "integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "bplist-creator": "0.1.0", + "bplist-parser": "0.3.1", + "plist": "^3.0.5" + } + }, + "node_modules/simple-plist/node_modules/bplist-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz", + "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/slugify": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz", + "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/stacktrace-parser": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz", + "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/str2buf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/str2buf/-/str2buf-1.3.0.tgz", + "integrity": "sha512-xIBmHIUHYZDP4HyoXGHYNVmxlXLXDrtFHYT0eV6IOdEj3VO9ccaF1Ejl9Oq8iFjITllpT8FhaXb4KsNmw+3EuA==", + "license": "MIT" + }, + "node_modules/stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", + "license": "Unlicense", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-ansi/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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/structured-headers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.4.1.tgz", + "integrity": "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.48.0.tgz", + "integrity": "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==", + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==", + "license": "MIT", + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "license": "BSD-3-Clause", + "optional": true, + "peer": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/toqr": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/toqr/-/toqr-0.1.1.tgz", + "integrity": "sha512-FWAPzCIHZHnrE/5/w9MPk0kK25hSQSH2IKhYh9PyjS3SG/+IEMvlwIHbhz+oF7xl54I+ueZlVnMjyzdSwLmAwA==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "license": "Unlicense" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typed-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz", + "integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==", + "license": "MIT", + "optionalDependencies": { + "rxjs": "*" + } + }, + "node_modules/undici": { + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", + "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "license": "MIT", + "optional": true, + "peer": true + }, + "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", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "optional": true, + "engines": { + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urlsafe-base64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz", + "integrity": "sha512-RtuPeMy7c1UrHwproMZN9gN6kiZ0SvJwRaEzwZY0j9MypEkFqyBaKv176jvlPtg58Zh36bOkS0NFABXMHvvGCA==" + }, + "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==", + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/valid-url": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/validator": { + "version": "13.15.35", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.35.tgz", + "integrity": "sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "license": "MIT" + }, + "node_modules/vlq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", + "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webcrypto-core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.9.2.tgz", + "integrity": "sha512-gsXecm82UQNlTBURJGuqOWy1Ww08S3kZUcr3aOJS02Pk0xLtkfeUAVC0u0xhgdonFme80edSJUIJyuvL/7250Q==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.7.0", + "@peculiar/json-schema": "^1.1.12", + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/webcrypto-core/node_modules/asn1js": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", + "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==", + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.5", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/webcrypto-shim": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/webcrypto-shim/-/webcrypto-shim-0.1.7.tgz", + "integrity": "sha512-JAvAQR5mRNRxZW2jKigWMjCMkjSdmP5cColRP1U/pTg69VgHXEi1orv5vVpJ55Zc5MIaPc1aaurzd9pjv2bveg==", + "license": "MIT" + }, + "node_modules/webex": { + "version": "2.60.0", + "resolved": "https://registry.npmjs.org/webex/-/webex-2.60.0.tgz", + "integrity": "sha512-lE/OTtxS9YG1jOVQFdFf8mcCRupyFfCHaLDMeJa32KdIi5oZAY5viYxiRnqpoQSpy3s66VbL8v1Dcv1TCiaDzg==", + "license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)", + "dependencies": { + "@babel/polyfill": "^7.12.1", + "@babel/runtime-corejs2": "^7.14.8", + "@webex/common": "2.60.0", + "@webex/internal-plugin-calendar": "2.60.0", + "@webex/internal-plugin-device": "2.60.0", + "@webex/internal-plugin-presence": "2.60.0", + "@webex/internal-plugin-support": "2.60.0", + "@webex/plugin-attachment-actions": "2.60.0", + "@webex/plugin-authorization": "2.60.0", + "@webex/plugin-device-manager": "2.60.0", + "@webex/plugin-logger": "2.60.0", + "@webex/plugin-meetings": "2.60.0", + "@webex/plugin-memberships": "2.60.0", + "@webex/plugin-messages": "2.60.0", + "@webex/plugin-people": "2.60.0", + "@webex/plugin-rooms": "2.60.0", + "@webex/plugin-team-memberships": "2.60.0", + "@webex/plugin-teams": "2.60.0", + "@webex/plugin-webhooks": "2.60.0", + "@webex/storage-adapter-local-storage": "2.60.0", + "@webex/webex-core": "2.60.0", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/webex-node-bot-framework": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/webex-node-bot-framework/-/webex-node-bot-framework-2.5.1.tgz", + "integrity": "sha512-aJ2KZMRsm+HpQ6oGZSJee678KY/p8VpRh+rsy+RFMj9xPdL1I4OOZ/xWjGOcXgwIqyiXg6tUn0nYrUf83T4JoQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "eventemitter2": "^6.4.9", + "https-proxy-agent": "^5.0.1", + "lodash": "4.17.21", + "moment": "^2.29.4", + "mongodb": "^3.5.7", + "validator": "^13.7.0", + "webex": "2.60.0", + "when": "^3.7.8" + }, + "engines": { + "npm": ">=8.3.0" + } + }, + "node_modules/webrtc-adapter": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.7.1.tgz", + "integrity": "sha512-TbrbBmiQBL9n0/5bvDdORc6ZfRY/Z7JnEj+EYOD1ghseZdpJ+nF2yx14k3LgQKc7JZnG7HAcL+zHnY25So9d7A==", + "license": "BSD-3-Clause", + "dependencies": { + "rtcpeerconnection-shim": "^1.2.15", + "sdp": "^2.12.0" + }, + "engines": { + "node": ">=6.0.0", + "npm": ">=3.10.0" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/whatwg-url-minimum": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/whatwg-url-minimum/-/whatwg-url-minimum-0.1.2.tgz", + "integrity": "sha512-XPEm0XFQWNVG292lII1PrRRJl3sItrs7CettZ4ncYxuDVpLyy+NwlGyut2hXI0JswcJUxeCH+CyOJK0ZzAXD6A==", + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/when": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", + "integrity": "sha512-5cZ7mecD3eYcMiCH4wtRPA5iFJZ50BJYDfckI5RRpQiktMiYTcn0ccLTZOvcbBume+1304fQztxeNzNS9Gvrnw==", + "license": "MIT" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "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/wrap-ansi/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==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ws": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xcode": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz", + "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "simple-plist": "^1.1.0", + "uuid": "^7.0.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/xcode/node_modules/uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "license": "MIT", + "dependencies": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/xml2js": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz", + "integrity": "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/xstate": { + "version": "4.38.3", + "resolved": "https://registry.npmjs.org/xstate/-/xstate-4.38.3.tgz", + "integrity": "sha512-SH7nAaaPQx57dx6qvfcIgqKRXIh4L0A1iYEqim4s1u7c9VoCgzZc+63FY90AKU4ZzOC2cfJzTnpO4zK7fCUzzw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/xstate" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "license": "MIT", + "optional": true, + "peer": true, + "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": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + } + }, + "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==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "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==", + "license": "MIT", + "optional": true, + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f63aeed --- /dev/null +++ b/package.json @@ -0,0 +1,40 @@ +{ + "name": "wbxcallprov", + "version": "2.0.0", + "description": "Webex Calling provisioning bot for retail stores", + "private": true, + "type": "module", + "main": "src/index.js", + "engines": { + "node": ">=20.0.0" + }, + "author": "Joseph B. McQueen", + "license": "ISC", + "scripts": { + "start": "node src/index.js", + "dev": "node --watch src/index.js", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "format": "prettier --write .", + "format:check": "prettier --check .", + "generate-911-csv": "node scripts/generate911Csv.js", + "fix-store-phones": "node scripts/fixStorePhones.js", + "agent:package": "./docker/remote-agent/package.sh", + "agent:check": "./docker/remote-agent/package.sh --check", + "agent:inspect": "./docker/remote-agent/inspect-bundle.sh" + }, + "dependencies": { + "dotenv": "^16.4.5", + "node-cron": "^3.0.3", + "undici": "^6.19.8", + "webex-node-bot-framework": "^2.5.1", + "ws": "^8.20.1" + }, + "devDependencies": { + "@eslint/js": "^9.9.0", + "eslint": "^9.9.0", + "eslint-config-prettier": "^9.1.0", + "globals": "^15.9.0", + "prettier": "^3.3.3" + } +} diff --git a/scripts/fixStorePhones.js b/scripts/fixStorePhones.js new file mode 100644 index 0000000..4e08fd2 --- /dev/null +++ b/scripts/fixStorePhones.js @@ -0,0 +1,36 @@ +#!/usr/bin/env node +/** + * One-shot cleanup for store users: normalize licensing and pin the default + * meeting site. Replaces the legacy phoneFix.js. + */ +import { getAllUsers, setDefaultMeetingSite } from '../src/webex/users.js'; +import { normalizeStoreUserLicenses } from '../src/webex/licensing.js'; +import { DEFAULT_DEFAULT_MEETING_SITE } from '../src/constants.js'; +import { logger } from '../src/logger.js'; + +async function main() { + logger.info('Fetching all Webex users...'); + const users = await getAllUsers(); + const storeUsers = users.filter((u) => u.firstName === 'Store'); + logger.info(`Found ${storeUsers.length} store users to normalize.`); + + for (const user of storeUsers) { + try { + await normalizeStoreUserLicenses(user); + logger.info(`${user.displayName} license normalized.`); + } catch (error) { + logger.error(`Error updating license for ${user.displayName}:`, error); + } + try { + await setDefaultMeetingSite(user.emails[0], DEFAULT_DEFAULT_MEETING_SITE); + logger.info(`${user.displayName} default site updated.`); + } catch (error) { + logger.error(`Error updating default site for ${user.displayName}:`, error); + } + } +} + +main().catch((error) => { + logger.error('fixStorePhones failed:', error); + process.exit(1); +}); diff --git a/scripts/generate911Csv.js b/scripts/generate911Csv.js new file mode 100644 index 0000000..a53576e --- /dev/null +++ b/scripts/generate911Csv.js @@ -0,0 +1,92 @@ +#!/usr/bin/env node +/** + * Merged replacement for the legacy get911.js and storeAddress.js scripts. + * Pulls the store list from SIW, validates each address with Google, looks up + * phone numbers with Twilio, and writes buildingFile.csv + locationFile.csv + * suitable for the E911 uploader. + * + * Usage: + * node scripts/generate911Csv.js [--env dev|prod] + * + * Defaults to prod. The SIW filter endpoint takes /Store/Filter/{page}/{size}/{sort}/{dir}. + */ +import fs from 'node:fs/promises'; +import { config } from '../src/config.js'; +import { getSIWData } from '../src/integrations/siw.js'; +import { validatePhoneNumber } from '../src/integrations/twilio.js'; +import { formatE911Address, formatSuite, validateAddress } from '../src/integrations/google.js'; +import { logger } from '../src/logger.js'; + +const BUILDING_HEADER = + '"Building Name *","Address *","Supplemental Info (20)","Organization Name Override (50)"\n'; +const LOCATION_HEADER = + '"Building Name *","Location Name *","Phone Number (10)","Alternate ID (50)","Callback Number (10)","Location Info (20)","Organization Name Override (50)","HTML Link Name (64)","HTML Link URL (1024)"\n'; + +function brandFor(brandCode) { + switch (brandCode) { + case 'AE': + return 'American Eagle'; + case 'AR': + return 'Aerie'; + default: + return 'American Eagle'; + } +} + +async function main() { + const args = process.argv.slice(2); + const envIndex = args.indexOf('--env'); + const envOverride = envIndex >= 0 ? args[envIndex + 1] : undefined; + const baseUrl = + envOverride === 'dev' ? config.siw.baseUrl.replace('-prod.', '-dev.') : config.siw.baseUrl; + const listUrl = `${baseUrl}/api/Store/Filter/1/9999/store_number/1`; + + logger.info(`Fetching stores from ${listUrl}`); + const stores = await getSIWData(listUrl); + + let buildingCsv = BUILDING_HEADER; + let locationCsv = LOCATION_HEADER; + let liveStores = 0; + + for (const store of stores.stores ?? []) { + const openInUsProd = + store.status_id === 2 && + store.environment_code === 'PRD' && + store.country_code === 'US' && + store.brand_code !== 'TS' && + store.store_number > 1000; + if (!openInUsProd) continue; + + try { + const googleAddress = await validateAddress( + `${store.address ?? ''} ${store.address2 ?? ''}`.trim(), + store.city, + store.state, + store.postal_code, + store.country_code, + ); + const formatted = formatE911Address(googleAddress); + const suite = formatSuite(googleAddress); + const phone = await validatePhoneNumber(store.phone); + const brand = brandFor(store.brand_code); + const padded = String(store.store_number).padStart(4, '0'); + + buildingCsv += `"Store ${padded}","${formatted}",,"${brand}"\n`; + locationCsv += `"Store ${padded}","Store ${padded}","${phone.phone_number}",,,"${suite}","${brand}",,\n`; + liveStores++; + } catch (error) { + logger.error(`Failed store ${store.store_number}:`, error); + } + } + + logger.info(`Live stores processed: ${liveStores}`); + await fs.writeFile('./buildingFile.csv', buildingCsv); + logger.info('buildingFile.csv saved.'); + await fs.writeFile('./locationFile.csv', locationCsv); + logger.info('locationFile.csv saved.'); +} + +main().catch((error) => { + logger.error('generate911Csv failed:', error); + process.exit(1); +}); diff --git a/src/cards/storeInfoCard.js b/src/cards/storeInfoCard.js new file mode 100644 index 0000000..3b1bc6a --- /dev/null +++ b/src/cards/storeInfoCard.js @@ -0,0 +1,66 @@ +/** + * Build the confirmation card shown before build/stage/migrate operations. + * `action` is what the "Yes" button posts back to the bot (buildStore, stageStore, migrateStore). + */ +export function buildStoreInfoCard(storeInfo, userInfo, action) { + const storeFacts = [ + { title: 'Name', value: storeInfo.name }, + { title: 'Brand', value: storeInfo.brand }, + { title: 'Status', value: storeInfo.status }, + { title: 'Extension', value: storeInfo.extension }, + { title: 'VoicePortal', value: storeInfo.vpExtension }, + { title: 'Street', value: storeInfo.address.address1 }, + { title: 'City', value: storeInfo.address.city }, + { title: 'State', value: storeInfo.address.state }, + { title: 'postalCode', value: storeInfo.address.postalCode }, + { title: 'Country', value: storeInfo.address.country }, + { title: 'phone', value: storeInfo.phoneNumber }, + { title: 'Time Zone', value: storeInfo.timeZone }, + ]; + + const userFacts = [ + { title: 'Display Name', value: userInfo.displayName }, + { title: 'First Name', value: userInfo.firstName }, + { title: 'Last Name', value: userInfo.lastName }, + ]; + + return { + type: 'AdaptiveCard', + $schema: 'http://adaptivecards.io/schemas/adaptive-card.json', + version: '1.3', + body: [ + { + type: 'TextBlock', + text: `Location: ${storeInfo.name}`, + wrap: true, + weight: 'Bolder', + size: 'Medium', + }, + { type: 'FactSet', facts: storeFacts }, + { + type: 'TextBlock', + text: `User: ${userInfo.emails[0]}`, + wrap: true, + weight: 'Bolder', + separator: true, + size: 'Medium', + }, + { type: 'FactSet', facts: userFacts }, + { type: 'TextBlock', text: 'Is this correct?', wrap: true, separator: true }, + ], + actions: [ + { + type: 'Action.Submit', + title: 'Yes', + id: 'btnBuildStore', + data: { action, storeInfo, userInfo }, + }, + { + type: 'Action.Submit', + title: 'No', + id: 'btnBadInfo', + data: { action: 'deleteCard' }, + }, + ], + }; +} diff --git a/src/cards/userInfoCard.js b/src/cards/userInfoCard.js new file mode 100644 index 0000000..b74dc66 --- /dev/null +++ b/src/cards/userInfoCard.js @@ -0,0 +1,185 @@ +import { findWebexUser, findWebexUserPhones, getWebexLicenses } from '../webex/users.js'; +import { findWebexLocationById, getLocationCallingDetails } from '../webex/locations.js'; +import { logger } from '../logger.js'; + +const DEFAULT_AVATAR = + 'https://thumbs.dreamstime.com/z/default-avatar-profile-icon-vector-unknown-social-media-user-photo-default-avatar-profile-icon-vector-unknown-social-media-user-184816085.jpg?w=768'; + +function userHeader(user) { + const avatarUrl = user.avatar || DEFAULT_AVATAR; + + const detailLines = []; + if (user.title) detailLines.push(user.title); + if (user.department) detailLines.push(user.department); + + const phoneFacts = (user.phoneNumbers ?? []).map((p) => ({ + title: p.type === 'work_extension' ? 'ext' : p.type, + value: p.value, + })); + + return { + type: 'ColumnSet', + columns: [ + { + type: 'Column', + items: [{ type: 'Image', style: 'Person', url: avatarUrl, size: 'Large' }], + width: 'auto', + horizontalAlignment: 'Left', + verticalContentAlignment: 'Top', + }, + { + type: 'Column', + items: [ + { + type: 'TextBlock', + weight: 'Bolder', + text: user.displayName, + wrap: true, + size: 'Medium', + }, + { + type: 'TextBlock', + spacing: 'None', + text: detailLines.join('\n'), + isSubtle: true, + wrap: true, + }, + { type: 'FactSet', facts: phoneFacts, spacing: 'None' }, + ], + width: 'auto', + horizontalAlignment: 'Left', + }, + ], + }; +} + +function accountFacts(user) { + const facts = []; + if (user.created) facts.push({ title: 'Created', value: user.created }); + if (user.lastModified) facts.push({ title: 'Modified', value: user.lastModified }); + if (user.lastActivity) facts.push({ title: 'Last Active', value: user.lastActivity }); + return { type: 'FactSet', facts, spacing: 'None' }; +} + +async function locationAction(user) { + try { + const [location, callingDetails] = await Promise.all([ + findWebexLocationById(user.locationId), + getLocationCallingDetails(user.locationId), + ]); + const facts = [ + { title: 'Name', value: location.name }, + { title: 'Address', value: location.address.address1 }, + { title: 'Timezone', value: location.timeZone }, + { title: 'Language', value: location.preferredLanguage }, + { title: 'Calling Line Name', value: callingDetails.callingLineId.name }, + { title: 'Calling Line Number', value: callingDetails.callingLineId.phoneNumber }, + { title: 'External Caller ID', value: callingDetails.externalCallerIdName }, + ]; + return { + type: 'Action.ShowCard', + title: 'Location Information', + card: { + type: 'AdaptiveCard', + body: [{ type: 'FactSet', facts }], + }, + }; + } catch (error) { + logger.error('Error getting location for user card:', error); + return null; + } +} + +async function licensesAction(user) { + const webexLicenses = await getWebexLicenses(); + const lookup = new Map(webexLicenses.map((l) => [l.id, l])); + const lines = (user.licenses ?? []) + .map((id) => lookup.get(id)) + .filter(Boolean) + .map((license) => + license.siteUrl ? `${license.name} (${license.siteUrl})` : license.name, + ); + return { + type: 'Action.ShowCard', + title: 'Licenses', + card: { + type: 'AdaptiveCard', + body: [{ type: 'TextBlock', text: lines.join('\n'), wrap: true }], + }, + }; +} + +async function devicesAction(user) { + try { + const phones = await findWebexUserPhones(user.id); + if (!phones?.items?.length) return null; + const choices = phones.items.map((device) => ({ + title: + device.type === 'phone' + ? `${device.displayName} - ${device.product}` + : `${device.displayName} - ${device.type}`, + value: device.id, + })); + return { + type: 'Action.ShowCard', + title: 'Devices', + card: { + type: 'AdaptiveCard', + body: [ + { + type: 'Input.ChoiceSet', + choices, + style: 'expanded', + isMultiSelect: true, + id: 'devices', + }, + { + type: 'ActionSet', + actions: [ + { + type: 'Action.Submit', + title: 'Show', + data: { action: 'showDevice' }, + }, + ], + }, + ], + }, + }; + } catch (error) { + logger.error('Error getting phones:', error); + return null; + } +} + +/** + * Build the informational user card. Renders whatever data we can retrieve + * and silently drops sections that fail (matching legacy behavior). + */ +export async function buildUserInfoCard(email) { + const user = await findWebexUser(email); + const infoCard = { + type: 'AdaptiveCard', + body: [userHeader(user), accountFacts(user)], + $schema: 'http://adaptivecards.io/schemas/adaptive-card.json', + version: '1.3', + actions: [], + }; + + const [locAction, licAction, devAction] = await Promise.all([ + locationAction(user), + licensesAction(user), + devicesAction(user), + ]); + for (const action of [locAction, licAction, devAction]) { + if (action) infoCard.actions.push(action); + } + + infoCard.actions.push({ + type: 'Action.Submit', + title: 'Remove Card', + data: { action: 'deleteCard' }, + }); + + return infoCard; +} diff --git a/src/commands/attachmentActions.js b/src/commands/attachmentActions.js new file mode 100644 index 0000000..a33c1e3 --- /dev/null +++ b/src/commands/attachmentActions.js @@ -0,0 +1,63 @@ +import { logger } from '../logger.js'; +import { buildStoreLocation } from '../flows/buildStore.js'; +import { stageStoreLocation } from '../flows/stageStore.js'; +import { migrateStoreLocation } from '../flows/migrateStore.js'; +import { getWebexDeviceDetail } from '../webex/devices.js'; + +async function runFlow(bot, trigger, verb, fn) { + const { storeInfo, userInfo } = trigger.attachmentAction.inputs; + bot.censor(trigger.attachmentAction.messageId); + bot.say(`${verb} ${storeInfo.name}.`); + try { + await fn(bot, storeInfo, userInfo); + bot.say(`Finished ${verb.toLowerCase()} ${storeInfo.name}.`); + } catch (error) { + logger.error(`${verb} failed for ${storeInfo?.name}:`, error); + bot.say(`Error ${verb.toLowerCase()} ${storeInfo?.name}: ${error.message}`); + } +} + +async function showDevices(bot, trigger) { + const deviceIds = (trigger.attachmentAction.inputs.devices ?? '').split(',').filter(Boolean); + for (const deviceId of deviceIds) { + try { + const detail = await getWebexDeviceDetail(deviceId); + bot.say('markdown', `\`\`\` json\n${JSON.stringify(detail, null, 2)}\n\`\`\`\n`); + } catch (error) { + logger.error('Failed to fetch device detail:', error); + bot.say(`Failed to fetch device ${deviceId}: ${error.message}`); + } + } +} + +export function register(framework) { + framework.on('attachmentAction', async (bot, trigger) => { + logger.debug('attachmentAction', JSON.stringify(trigger)); + const action = trigger.attachmentAction.inputs.action; + + switch (action) { + case 'buildStore': + await runFlow(bot, trigger, 'Building', buildStoreLocation); + break; + case 'stageStore': + await runFlow(bot, trigger, 'Staging', stageStoreLocation); + break; + case 'migrateStore': + await runFlow(bot, trigger, 'Migrating store', migrateStoreLocation); + break; + case 'showDevice': + await showDevices(bot, trigger); + break; + case 'deleteCard': + bot.censor(trigger.attachmentAction.messageId); + break; + default: + if (trigger.attachmentAction.inputs.responseTo === 'badInfo') { + bot.say( + 'If information is not correct, please check Store Info Web or contact the administrator.', + ); + } + break; + } + }); +} diff --git a/src/commands/buildStore.js b/src/commands/buildStore.js new file mode 100644 index 0000000..7f62d75 --- /dev/null +++ b/src/commands/buildStore.js @@ -0,0 +1,29 @@ +import { logger } from '../logger.js'; +import { getStoreInfo } from '../integrations/siw.js'; +import { findWebexUser } from '../webex/users.js'; +import { buildStoreInfoCard } from '../cards/storeInfoCard.js'; +import { parseStoreArg, storeEmail } from './helpers.js'; + +export function register(framework) { + framework.hears( + /\/buildstore/i, + async (bot, trigger) => { + logger.info(`${trigger.person.displayName} ran the buildStore command.`); + const storeNumber = parseStoreArg(trigger); + if (!storeNumber) { + bot.say("You didn't enter a store number."); + return; + } + try { + const storeInfo = await getStoreInfo(storeNumber); + const userInfo = await findWebexUser(storeEmail(storeNumber)); + const card = buildStoreInfoCard(storeInfo, userInfo, 'buildStore'); + bot.sendCard(card, 'Please use another client'); + } catch (error) { + logger.error('buildStore command failed:', error); + bot.say('markdown', `Error running /buildstore:\n\`\`\`\n${error.message}\n\`\`\``); + } + }, + '**/buildStore** - Builds a store location for Webex Calling (New and remodels).', + ); +} diff --git a/src/commands/helpers.js b/src/commands/helpers.js new file mode 100644 index 0000000..86af743 --- /dev/null +++ b/src/commands/helpers.js @@ -0,0 +1,36 @@ +export function storeEmail(storeNumber) { + return `ae${String(storeNumber).padStart(5, '0')}@ae.com`; +} + +/** + * Pull the first argument out of a webex-node-bot-framework trigger. + * + * For a message like `/storeInfo 792` matched by `/\/storeinfo/i`, the + * framework populates: + * trigger.command = "/storeInfo" // the matched substring + * trigger.prompt = " 792" // everything AFTER the match + * + * (See node_modules/webex-node-bot-framework/lib/framework.js + * calcCommandAndPrompt — it does textForCommandAndPrompt.slice(match.index + * + match[0].length), which explicitly excludes the command itself.) + * + * This also works in @-mentioned group rooms because the framework strips + * the bot's display name from textForCommandAndPrompt before slicing. + */ +export function parseStoreArg(trigger) { + const prompt = (trigger?.prompt ?? '').trim(); + if (prompt) return prompt.split(/\s+/)[0]; + + // Fallback for edge cases where prompt isn't populated: pull the token + // immediately after the command from trigger.args. args[0] is the + // command in DMs, so args[1] is our target. In mentioned group rooms + // args[0] is the bot name and args[1] is the command, so we search for + // the first token starting with '/' and take the one after it. + const args = Array.isArray(trigger?.args) ? trigger.args : []; + for (let i = 0; i < args.length - 1; i++) { + if (typeof args[i] === 'string' && args[i].startsWith('/')) { + return args[i + 1]; + } + } + return undefined; +} diff --git a/src/commands/migrateStore.js b/src/commands/migrateStore.js new file mode 100644 index 0000000..e774066 --- /dev/null +++ b/src/commands/migrateStore.js @@ -0,0 +1,33 @@ +import { logger } from '../logger.js'; +import { getStoreInfo } from '../integrations/siw.js'; +import { findWebexUser } from '../webex/users.js'; +import { buildStoreInfoCard } from '../cards/storeInfoCard.js'; +import { parseStoreArg, storeEmail } from './helpers.js'; + +export function register(framework) { + framework.hears( + /\/migratestore/i, + async (bot, trigger) => { + logger.info(`${trigger.person.displayName} ran the migrateStore command.`); + const storeNumber = parseStoreArg(trigger); + if (!storeNumber) { + bot.say("You didn't enter a store number."); + return; + } + try { + const storeInfo = await getStoreInfo(storeNumber); + storeInfo.extension = `5${String(storeNumber).padStart(4, '0')}`; + const userInfo = await findWebexUser(storeEmail(storeNumber)); + const card = buildStoreInfoCard(storeInfo, userInfo, 'migrateStore'); + bot.sendCard(card, 'Please use another client'); + } catch (error) { + logger.error('migrateStore command failed:', error); + bot.say( + 'markdown', + `Error running /migratestore:\n\`\`\`\n${error.message}\n\`\`\``, + ); + } + }, + '**/migrateStore** - Completes the store migration for an open store.', + ); +} diff --git a/src/commands/stageStore.js b/src/commands/stageStore.js new file mode 100644 index 0000000..d059a71 --- /dev/null +++ b/src/commands/stageStore.js @@ -0,0 +1,30 @@ +import { logger } from '../logger.js'; +import { getStoreInfo } from '../integrations/siw.js'; +import { findWebexUser } from '../webex/users.js'; +import { buildStoreInfoCard } from '../cards/storeInfoCard.js'; +import { parseStoreArg, storeEmail } from './helpers.js'; + +export function register(framework) { + framework.hears( + /\/stagestore/i, + async (bot, trigger) => { + logger.info(`${trigger.person.displayName} ran the stageStore command.`); + const storeNumber = parseStoreArg(trigger); + if (!storeNumber) { + bot.say("You didn't enter a store number."); + return; + } + try { + const storeInfo = await getStoreInfo(storeNumber); + storeInfo.extension = `8${String(storeNumber).padStart(4, '0')}`; + const userInfo = await findWebexUser(storeEmail(storeNumber)); + const card = buildStoreInfoCard(storeInfo, userInfo, 'stageStore'); + bot.sendCard(card, 'Please use another client'); + } catch (error) { + logger.error('stageStore command failed:', error); + bot.say('markdown', `Error running /stagestore:\n\`\`\`\n${error.message}\n\`\`\``); + } + }, + '**/stageStore** - Stages a store location for Webex Calling (Pre-migration).', + ); +} diff --git a/src/commands/storeInfo.js b/src/commands/storeInfo.js new file mode 100644 index 0000000..2225637 --- /dev/null +++ b/src/commands/storeInfo.js @@ -0,0 +1,25 @@ +import { logger } from '../logger.js'; +import { buildUserInfoCard } from '../cards/userInfoCard.js'; +import { parseStoreArg, storeEmail } from './helpers.js'; + +export function register(framework) { + framework.hears( + /\/storeinfo/i, + async (bot, trigger) => { + logger.info(`${trigger.person.displayName} ran the storeInfo command.`); + const storeNumber = parseStoreArg(trigger); + if (!storeNumber) { + bot.say("You didn't enter a store number."); + return; + } + try { + const card = await buildUserInfoCard(storeEmail(storeNumber)); + bot.sendCard(card, 'Use a proper client...'); + } catch (error) { + logger.error('storeInfo command failed:', error); + bot.say(`Error finding store user information: ${error.message}`); + } + }, + '**/storeinfo** - Shows store information', + ); +} diff --git a/src/commands/userInfo.js b/src/commands/userInfo.js new file mode 100644 index 0000000..8e6c310 --- /dev/null +++ b/src/commands/userInfo.js @@ -0,0 +1,25 @@ +import { logger } from '../logger.js'; +import { buildUserInfoCard } from '../cards/userInfoCard.js'; +import { parseStoreArg } from './helpers.js'; + +export function register(framework) { + framework.hears( + /\/userInfo/i, + async (bot, trigger) => { + logger.info(`${trigger.person.displayName} ran the userInfo command.`); + const email = parseStoreArg(trigger); + if (!email) { + bot.say("You didn't enter a user email."); + return; + } + try { + const card = await buildUserInfoCard(email); + bot.sendCard(card, 'Use a proper client...'); + } catch (error) { + logger.error('userInfo command failed:', error); + bot.say(`Error finding user information: ${error.message}`); + } + }, + '**/userInfo** - Shows user information', + ); +} diff --git a/src/config.js b/src/config.js new file mode 100644 index 0000000..cc33f45 --- /dev/null +++ b/src/config.js @@ -0,0 +1,86 @@ +import 'dotenv/config'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const projectRoot = path.resolve(__dirname, '..'); + +function required(name) { + const value = process.env[name]; + if (value === undefined || value === '') { + throw new Error(`Missing required environment variable: ${name}`); + } + return value; +} + +function optional(name, fallback) { + const value = process.env[name]; + return value === undefined || value === '' ? fallback : value; +} + +function resolvePath(value) { + return path.isAbsolute(value) ? value : path.resolve(projectRoot, value); +} + +function integer(name, fallback) { + const value = process.env[name]; + if (value === undefined || value === '') return fallback; + const parsed = Number.parseInt(value, 10); + if (!Number.isInteger(parsed) || parsed < 1 || parsed > 65535) { + throw new Error(`Environment variable ${name} must be an integer between 1 and 65535`); + } + return parsed; +} + +export const config = { + projectRoot, + nodeEnv: optional('NODE_ENV', 'development'), + logLevel: optional('LOG_LEVEL', 'info'), + + ws: { + // Port this bot listens on for the remote SIW agent to connect back to. + port: integer('WS_PORT', 8080), + // Shared secret the agent must present as Bearer token (or ?token= query). + token: required('WS_TOKEN'), + }, + + webexBot: { + token: required('WEBEX_BOT_TOKEN'), + name: optional('WEBEX_BOT_NAME', 'AEO Call Provisioning'), + userName: optional('WEBEX_BOT_USERNAME', ''), + botId: optional('WEBEX_BOT_ID', ''), + webhookRequestJSONLocation: 'body', + removeWebhooksOnStart: true, + removeDeviceRegistrationsOnStart: true, + }, + + webexService: { + clientId: required('WEBEX_SVC_CLIENT_ID'), + clientSecret: required('WEBEX_SVC_CLIENT_SECRET'), + tokenStorePath: resolvePath(optional('WEBEX_TOKEN_STORE', './config/wbxTokens.json')), + }, + + twilio: { + accountSid: required('TWILIO_ACCOUNT_SID'), + authToken: required('TWILIO_AUTH_TOKEN'), + }, + + siw: { + baseUrl: optional('SIW_BASE_URL', 'https://storeinfoweb-prod.ae.com').replace(/\/$/, ''), + userName: required('SIW_USERNAME'), + password: required('SIW_PASSWORD'), + }, + + google: { + apiKey: required('GOOGLE_API_KEY'), + // Path to a service-account JSON key file. Optional — only set when + // future code needs google-auth-library-style credentials. The file + // itself lives outside of git. + serviceAccountKeyPath: (() => { + const raw = optional('GOOGLE_APPLICATION_CREDENTIALS', ''); + return raw ? resolvePath(raw) : null; + })(), + }, +}; + +export default config; diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 0000000..c69e7de --- /dev/null +++ b/src/constants.js @@ -0,0 +1,115 @@ +// Organization-scoped identifiers pulled out of the legacy index.js. +// These are not secrets (they are Webex resource IDs and SIP details), +// but they are org-specific, so keeping them in one file makes future +// tenant/environment changes a single-file diff. + +export const WEBEX_API_BASE = 'https://webexapis.com/v1'; + +export const ROUTE_GROUPS = { + US: { + id: 'Y2lzY29zcGFyazovL3VzL1JPVVRFX0dST1VQLzViMjc1ZmYzLTI0NTUtNDYwOC1iMzI4LTZlMThhOGViMDk1Mg', + name: 'Stores', + }, + CA: { + id: 'Y2lzY29zcGFyazovL3VzL1JPVVRFX0dST1VQLzNlZjY5NmVlLThhYzUtNGI3Ni05M2YxLWQ1N2I0NTdiMmRjMA', + name: 'Stores Canada', + }, +}; + +export const MUSIC_ON_HOLD = { + announcementId: + 'Y2lzY29zcGFyazovL3VzL0FOTk9VTkNFTUVOVC9mNDExYTY2Yy1jMmRhLTQ3ODgtOTNhYi04OTU1NzBhYjM3N2Q', + fileName: 'MusicOnHold.wav', +}; + +// Webex license identifiers (subscription-specific). +export const LICENSES = { + // License to add when granting Webex Calling to a store user (BroadCloud). + STORE_CALLING: + 'Y2lzY29zcGFyazovL3VzL0xJQ0VOU0UvZGI5Y2RjMzEtOGY4ZS00MGI0LTkxNmMtOGQ5ZTljOTJlNzBkOkJDU1REXzAwNDQyMWYyLWQ4NzUtNGNhYi04NjBmLWZlYWVmMzA0ZTExOA', + + // License granted to store users during clean-up. + STORE_MEETINGS_ADD: + 'Y2lzY29zcGFyazovL3VzL0xJQ0VOU0UvZGI5Y2RjMzEtOGY4ZS00MGI0LTkxNmMtOGQ5ZTljOTJlNzBkOkVFXzVhMjg5MDRmLWFmOGUtNDY3ZC1iMTY2LTQ1NWU5YjZjYTIwZF9hZW9zdG9yZXMud2ViZXguY29t', + + // Licenses to remove during clean-up (obsolete trial/preview/free tiers). + LEGACY_TO_REMOVE: [ + 'Y2lzY29zcGFyazovL3VzL0xJQ0VOU0UvZGI5Y2RjMzEtOGY4ZS00MGI0LTkxNmMtOGQ5ZTljOTJlNzBkOkZUQ19hMjQ3MzgyOC1hOTgwLTQ3MmYtODE5ZC02YjljY2UwOGU5MmI', + 'Y2lzY29zcGFyazovL3VzL0xJQ0VOU0UvZGI5Y2RjMzEtOGY4ZS00MGI0LTkxNmMtOGQ5ZTljOTJlNzBkOkNGX2VlNWI4YWU3LTExM2EtNGYyNC05ZjQyLTdhNWM0M2ZlNzllZg', + 'Y2lzY29zcGFyazovL3VzL0xJQ0VOU0UvZGI5Y2RjMzEtOGY4ZS00MGI0LTkxNmMtOGQ5ZTljOTJlNzBkOkZUTV9mNWZkZTM1Zi00NzA0LTQ2MGEtODEwZi00YzVkMzUyNDFlNjk', + 'Y2lzY29zcGFyazovL3VzL0xJQ0VOU0UvZGI5Y2RjMzEtOGY4ZS00MGI0LTkxNmMtOGQ5ZTljOTJlNzBkOk1TXzZiMzYxZmI5LTc5NmQtNGY0Yy1hNGI1LWIwODEzM2JmZmZlNw', + 'Y2lzY29zcGFyazovL3VzL0xJQ0VOU0UvZGI5Y2RjMzEtOGY4ZS00MGI0LTkxNmMtOGQ5ZTljOTJlNzBkOkZNU185ZWNhNzgxNC0zMzEzLTQ2NGYtOTY0Mi0wMjM5ODc1YmM5Zjg', + 'Y2lzY29zcGFyazovL3VzL0xJQ0VOU0UvZGI5Y2RjMzEtOGY4ZS00MGI0LTkxNmMtOGQ5ZTljOTJlNzBkOldYU0ZSRUVfYWExOWZjNTctZTFmOS00YTkwLTk2MjctYzM2ZjAwZGM5N2YxX2FlbzJnby10ZXN0LndlYmV4LmNvbQ', + 'Y2lzY29zcGFyazovL3VzL0xJQ0VOU0UvZGI5Y2RjMzEtOGY4ZS00MGI0LTkxNmMtOGQ5ZTljOTJlNzBkOkVFXzIwNTM3OGM0LTA2NmYtNDM1ZC04MGZkLTc5MDdiMjJkMDBlMF9hZW8yZ28tcHJldmlldy53ZWJleC5jb20', + 'Y2lzY29zcGFyazovL3VzL0xJQ0VOU0UvZGI5Y2RjMzEtOGY4ZS00MGI0LTkxNmMtOGQ5ZTljOTJlNzBkOldYU0ZSRUVfN2UxZjFhNDAtOTVjOC00YzkyLWI5MDEtMTA4MmZjNmQ2YWEwX2FlbzJnby53ZWJleC5jb20', + 'Y2lzY29zcGFyazovL3VzL0xJQ0VOU0UvZGI5Y2RjMzEtOGY4ZS00MGI0LTkxNmMtOGQ5ZTljOTJlNzBkOkVFX2FjZTJlZjAyLTY2YzEtNDc0OC05YjhmLTRhOTdiNDIwMzdlM19hZW8yZ28ud2ViZXguY29t', + ], +}; + +// Webex meeting sites to enroll every store user in. +export const MEETING_SITES = [ + { siteUrl: 'aeo2go.webex.com', accountType: 'attendee', operation: 'add' }, + { siteUrl: 'aeostores.webex.com', operation: 'add' }, +]; + +export const DEFAULT_DEFAULT_MEETING_SITE = 'aeostores.webex.com'; + +// Caller-ID / voicemail defaults for a newly built location. +export const CALLER_ID = { + externalCallerIdName: 'American Eagle Outfitters', + locationFallbackNumber: '+15153186064', + customExternalCallerIdName: 'American Eagle', +}; + +export const VOICE_PORTAL_PASSCODE = '147369'; + +// Store brand -> greeting audio file (relative to project root). +export const GREETINGS = { + 'American Eagle Outfitters': { file: 'greetings/AEGreeting.wav', label: 'AE Greeting' }, + Aerie: { file: 'greetings/AerieGreeting.wav', label: 'Aerie Greeting' }, + Offline: { file: 'greetings/OfflineGreeting.wav', label: 'Offline Greeting' }, + Unsubscribed: { file: 'greetings/UnsubscribedGreeting.wav', label: 'Unsubscribed Greeting' }, +}; + +// Timezone remapping. Webex Calling doesn't accept some IANA zones that Google returns, +// so we translate them to the nearest supported equivalent. +export const TIMEZONE_ALIASES = { + 'America/Toronto': 'America/Montreal', + 'America/Indiana/Indianapolis': 'America/New_York', + 'America/Boise': 'America/Denver', + 'America/Detroit': 'America/New_York', + 'America/Matamoros': 'America/Chicago', +}; + +// Standard set of outgoing calling permissions applied to every store location. +export const OUTGOING_CALLING_PERMISSIONS = [ + { callType: 'INTERNAL_CALL', action: 'ALLOW', transferEnabled: true }, + { callType: 'LOCAL', action: 'ALLOW', transferEnabled: false }, + { callType: 'TOLL_FREE', action: 'ALLOW', transferEnabled: false }, + { callType: 'TOLL', action: 'ALLOW', transferEnabled: false }, + { callType: 'NATIONAL', action: 'ALLOW', transferEnabled: false }, + { callType: 'INTERNATIONAL', action: 'BLOCK', transferEnabled: false }, + { callType: 'OPERATOR_ASSISTED', action: 'BLOCK', transferEnabled: false }, + { callType: 'CHARGEABLE_DIRECTORY_ASSISTED', action: 'BLOCK', transferEnabled: false }, + { callType: 'SPECIAL_SERVICES_I', action: 'BLOCK', transferEnabled: false }, + { callType: 'SPECIAL_SERVICES_II', action: 'BLOCK', transferEnabled: false }, + { callType: 'PREMIUM_SERVICES_I', action: 'BLOCK', transferEnabled: false }, + { callType: 'PREMIUM_SERVICES_II', action: 'BLOCK', transferEnabled: false }, + { callType: 'CASUAL', action: 'BLOCK', transferEnabled: false }, + { callType: 'URL_DIALING', action: 'ALLOW', transferEnabled: true }, + { callType: 'UNKNOWN', action: 'ALLOW', transferEnabled: true }, +]; + +export default { + WEBEX_API_BASE, + ROUTE_GROUPS, + MUSIC_ON_HOLD, + LICENSES, + MEETING_SITES, + DEFAULT_DEFAULT_MEETING_SITE, + CALLER_ID, + VOICE_PORTAL_PASSCODE, + GREETINGS, + TIMEZONE_ALIASES, + OUTGOING_CALLING_PERMISSIONS, +}; diff --git a/src/flows/buildStore.js b/src/flows/buildStore.js new file mode 100644 index 0000000..ee27173 --- /dev/null +++ b/src/flows/buildStore.js @@ -0,0 +1,70 @@ +import { + addPhoneNumbersToLocation, + createLocation, + enableLocationForCalling, + updateInternalDialing, + updateLocationOutgoingPermission, + updateLocationRouteGroup, + updateLocationVoicemail, + updateLocationVoicePortal, + updateMusicOnHold, +} from '../webex/locations.js'; +import { scheduleStoreDeviceSettings } from '../webex/devices.js'; +import { createAllHoursSchedule } from '../webex/schedules.js'; +import { uploadGreeting } from '../webex/announcements.js'; +import { addWebexCallingToStoreUser, normalizeStoreUserLicenses } from '../webex/licensing.js'; +import { updateUserCallExperience } from '../webex/users.js'; +import { logger } from '../logger.js'; +import { runStep } from './stepRunner.js'; +import { greetingForBrand } from './greetingSelector.js'; + +/** + * "Build store" — full green-field provisioning: create location, calling, + * greeting, user attach, license cleanup. + */ +export async function buildStoreLocation(bot, locationInfo, userInfo) { + logger.info(`Building location ${locationInfo.name}`); + const location = await createLocation(locationInfo); + bot.say( + 'markdown', + `
Created location ${location.name}.
`, + ); + + await runStep(bot, 'Enabled location for Webex Calling', () => + enableLocationForCalling(location), + ); + await runStep(bot, 'Updated location Webex Calling connection', () => + updateLocationRouteGroup(location), + ); + await runStep(bot, 'Added phone numbers to location', () => + addPhoneNumbersToLocation(location, locationInfo.phoneNumber), + ); + await runStep(bot, 'Updated internal dialing', () => updateInternalDialing(location)); + await runStep(bot, 'Updated location outgoing permission', () => + updateLocationOutgoingPermission(location), + ); + await runStep(bot, 'Updated music on hold', () => updateMusicOnHold(location)); + await runStep(bot, 'Updated location voicemail', () => updateLocationVoicemail(location)); + await runStep(bot, 'Updated location voice portal', () => + updateLocationVoicePortal(location, locationInfo.vpExtension), + ); + await runStep(bot, 'Created a schedule', () => createAllHoursSchedule(location)); + await runStep(bot, 'Scheduled device changes', () => scheduleStoreDeviceSettings(location)); + + const { file, fileName } = greetingForBrand(locationInfo); + const greeting = await runStep(bot, 'Succeeded uploading greeting', () => + uploadGreeting(location, file, fileName), + ); + if (greeting) location.announcementId = greeting.id; + + await runStep(bot, 'Updated store user', () => + addWebexCallingToStoreUser(location, userInfo, locationInfo.extension), + ); + await runStep(bot, 'Updated user call application experience', () => + updateUserCallExperience(userInfo), + ); + await runStep(bot, 'Fixed Licenses', () => normalizeStoreUserLicenses(userInfo)); + + bot.say('Build Complete!'); + return location; +} diff --git a/src/flows/greetingSelector.js b/src/flows/greetingSelector.js new file mode 100644 index 0000000..e432d0d --- /dev/null +++ b/src/flows/greetingSelector.js @@ -0,0 +1,13 @@ +import { GREETINGS } from '../constants.js'; + +/** + * Pick the correct greeting audio file + filename for a given location's brand. + * Falls back to the AE greeting if the brand isn't recognized. + */ +export function greetingForBrand(locationInfo) { + const entry = GREETINGS[locationInfo.brand] ?? GREETINGS['American Eagle Outfitters']; + return { + file: entry.file, + fileName: `${locationInfo.storeNumber} - ${entry.label}.wav`, + }; +} diff --git a/src/flows/migrateStore.js b/src/flows/migrateStore.js new file mode 100644 index 0000000..b81b25e --- /dev/null +++ b/src/flows/migrateStore.js @@ -0,0 +1,75 @@ +import { + addPhoneNumbersToLocation, + findWebexLocation, + updateLocationCallingIdentity, +} from '../webex/locations.js'; +import { findLocationAnnouncements } from '../webex/announcements.js'; +import { createStoreAutoAttendant } from '../webex/autoAttendants.js'; +import { normalizeStoreUserLicenses } from '../webex/licensing.js'; +import { + updateUserCallExperience, + updateUserCallerId, + updateUserExtension, + updateUserVoicemailSettings, +} from '../webex/users.js'; +import { CALLER_ID } from '../constants.js'; +import { logger } from '../logger.js'; +import { runStep } from './stepRunner.js'; + +/** + * "Migrate store" — finish the cut-over for a store that was previously staged. + * Attach the phone number, set caller ID, create the auto-attendant, and clean + * up the user's licensing/voicemail. + */ +export async function migrateStoreLocation(bot, locationInfo, userInfo) { + logger.info(`Migrating location ${locationInfo.name}`); + const matches = await findWebexLocation(locationInfo.name); + if (!matches.length) { + throw new Error( + `No existing Webex location found for ${locationInfo.name}. Did you stage first?`, + ); + } + const location = matches[0]; + + await runStep(bot, 'Added phone numbers to location', () => + addPhoneNumbersToLocation(location, locationInfo.phoneNumber), + ); + await runStep(bot, 'Updated location Webex Calling Details', () => + updateLocationCallingIdentity(location, locationInfo.phoneNumber), + ); + await runStep(bot, 'Updated user extension', () => + updateUserExtension(userInfo, locationInfo.extension), + ); + await runStep(bot, 'Updated user call application experience', () => + updateUserCallExperience(userInfo), + ); + await runStep(bot, 'Updated user Caller ID Information', () => + updateUserCallerId(userInfo, locationInfo.extension, locationInfo.phoneNumber, { + locationFallbackNumber: CALLER_ID.locationFallbackNumber, + customExternalCallerIdName: CALLER_ID.customExternalCallerIdName, + }), + ); + await runStep(bot, 'Updated user voicemail settings', () => + updateUserVoicemailSettings(userInfo), + ); + + const announcements = await runStep(bot, 'Located store announcement', () => + findLocationAnnouncements(location), + ); + if (announcements && announcements[0]) { + location.announcementId = announcements[0].id; + await runStep(bot, 'Created auto attendant', () => + createStoreAutoAttendant(location, locationInfo), + ); + } else { + bot.say( + 'markdown', + "
Skipping auto attendant: no location announcement found.
", + ); + } + + await runStep(bot, 'Fixed Licenses', () => normalizeStoreUserLicenses(userInfo)); + + bot.say('Migration Complete!'); + return location; +} diff --git a/src/flows/stageStore.js b/src/flows/stageStore.js new file mode 100644 index 0000000..a594771 --- /dev/null +++ b/src/flows/stageStore.js @@ -0,0 +1,57 @@ +import { + createLocation, + enableLocationForCalling, + updateInternalDialing, + updateLocationOutgoingPermission, + updateLocationVoicemail, + updateLocationVoicePortal, + updateMusicOnHold, +} from '../webex/locations.js'; +import { scheduleStoreDeviceSettings } from '../webex/devices.js'; +import { createAllHoursSchedule } from '../webex/schedules.js'; +import { uploadGreeting } from '../webex/announcements.js'; +import { addWebexCallingToStoreUser } from '../webex/licensing.js'; +import { logger } from '../logger.js'; +import { runStep } from './stepRunner.js'; +import { greetingForBrand } from './greetingSelector.js'; + +/** + * "Stage store" — pre-migration setup: location + calling + user, but without + * phone-number attachment or full licensing cleanup (that happens at migrate time). + */ +export async function stageStoreLocation(bot, locationInfo, userInfo) { + logger.info(`Staging location ${locationInfo.name}`); + const location = await createLocation(locationInfo); + bot.say( + 'markdown', + `
Created location ${location.name}.
`, + ); + + await runStep(bot, 'Enabled location for Webex Calling', () => + enableLocationForCalling(location), + ); + await runStep(bot, 'Updated internal dialing', () => updateInternalDialing(location)); + await runStep(bot, 'Updated location outgoing permission', () => + updateLocationOutgoingPermission(location), + ); + await runStep(bot, 'Updated music on hold', () => updateMusicOnHold(location)); + await runStep(bot, 'Updated location voicemail', () => updateLocationVoicemail(location)); + await runStep(bot, 'Updated location voice portal', () => + updateLocationVoicePortal(location, locationInfo.vpExtension), + ); + await runStep(bot, 'Created a schedule', () => createAllHoursSchedule(location)); + await runStep(bot, 'Scheduled device changes', () => scheduleStoreDeviceSettings(location)); + + const { file, fileName } = greetingForBrand(locationInfo); + const greeting = await runStep(bot, 'Succeeded uploading greeting', () => + uploadGreeting(location, file, fileName), + ); + if (greeting) location.announcementId = greeting.id; + + await runStep(bot, 'Updated store user', () => + addWebexCallingToStoreUser(location, userInfo, locationInfo.extension), + ); + + bot.say('Staging Complete!'); + return location; +} diff --git a/src/flows/stepRunner.js b/src/flows/stepRunner.js new file mode 100644 index 0000000..2c2177e --- /dev/null +++ b/src/flows/stepRunner.js @@ -0,0 +1,21 @@ +import { logger } from '../logger.js'; + +/** + * Run a provisioning step, log its outcome to console + bot chat, and return + * the step's resolved value (or undefined on failure). Never throws — matches + * the legacy behavior where each step's error was captured but did not halt + * the flow. + */ +export async function runStep(bot, description, fn, { successMessage, failureMessage } = {}) { + try { + const result = await fn(); + const msg = successMessage ?? description; + bot?.say('markdown', `
${msg}
`); + return result; + } catch (error) { + logger.error(`${description} failed:`, error); + const msg = failureMessage ?? `Error: ${description}`; + bot?.say('markdown', `
${msg}
`); + return undefined; + } +} diff --git a/src/http.js b/src/http.js new file mode 100644 index 0000000..40ad0bd --- /dev/null +++ b/src/http.js @@ -0,0 +1,67 @@ +import { logger } from './logger.js'; + +/** + * Wrapper around native fetch that transparently retries on HTTP 429 by + * honoring the Retry-After header (defaulting to 1 second if missing). + * Bounded by `maxRetries` to prevent infinite loops. + */ +export async function fetchWithRateLimit(url, options = {}, { maxRetries = 5 } = {}) { + for (let attempt = 0; attempt <= maxRetries; attempt++) { + const response = await fetch(url, options); + if (response.status !== 429) return response; + + const retryAfterHeader = response.headers.get('retry-after'); + const waitSeconds = Number(retryAfterHeader); + const delayMs = Number.isFinite(waitSeconds) && waitSeconds > 0 ? waitSeconds * 1000 : 1000; + logger.warn( + `429 from ${url}. Waiting ${delayMs}ms (attempt ${attempt + 1}/${maxRetries}).`, + ); + await new Promise((r) => setTimeout(r, delayMs)); + } + return fetch(url, options); +} + +/** + * Send a JSON-bodied request and parse the response as JSON when there is one. + * Throws a descriptive Error on non-2xx responses. + * + * @param {string} method + * @param {string} url + * @param {object|string|undefined} body plain object (will be JSON.stringify'd) or pre-serialized string + * @param {object} [extra] extra fetch options merged in (headers, dispatcher, ...) + */ +export async function requestJson(method, url, body, extra = {}) { + const headers = { + 'Content-Type': 'application/json', + ...(extra.headers ?? {}), + }; + const options = { + method, + headers, + ...extra, + }; + if (body !== undefined && body !== null) { + options.body = typeof body === 'string' ? body : JSON.stringify(body); + } + + const response = await fetchWithRateLimit(url, options); + if (!response.ok) { + const errorText = await response.text().catch(() => ''); + const error = new Error( + `HTTP ${response.status} ${response.statusText} for ${method} ${url}${errorText ? `\n${errorText}` : ''}`, + ); + error.status = response.status; + error.body = errorText; + throw error; + } + + if (response.status === 204) return undefined; + const contentType = response.headers.get('content-type') ?? ''; + if (!contentType.includes('application/json')) { + const text = await response.text(); + return text === '' ? undefined : text; + } + + const text = await response.text(); + return text === '' ? undefined : JSON.parse(text); +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..1584629 --- /dev/null +++ b/src/index.js @@ -0,0 +1,95 @@ +import cron from 'node-cron'; +import Framework from 'webex-node-bot-framework'; +import { config } from './config.js'; +import { logger } from './logger.js'; +import { isAccessTokenExpiring, refreshAccessToken } from './webex/auth.js'; +import { startWebSocketServer, stopWebSocketServer } from './services/websocket.js'; +import { register as registerBuildStore } from './commands/buildStore.js'; +import { register as registerStageStore } from './commands/stageStore.js'; +import { register as registerMigrateStore } from './commands/migrateStore.js'; +import { register as registerStoreInfo } from './commands/storeInfo.js'; +import { register as registerUserInfo } from './commands/userInfo.js'; +import { register as registerAttachmentActions } from './commands/attachmentActions.js'; + +const framework = new Framework(config.webexBot); + +framework.on('initialized', () => { + framework.debug('Framework initialized successfully! [Press CTRL-C to quit]'); +}); + +framework.on('log', (msg) => { + logger.info(msg); +}); + +registerBuildStore(framework); +registerStageStore(framework); +registerMigrateStore(framework); +registerStoreInfo(framework); +registerUserInfo(framework); +registerAttachmentActions(framework); + +// Match `/help` (with the leading slash, matching the convention of every +// other command). The framework's string-phrase matcher only compares the +// FIRST whitespace-delimited token, so plain `'help'` wouldn't match +// `/help` — that's why we register a regex. +framework.hears( + /\/help\b/i, + (bot) => bot.say('markdown', framework.showHelp()), + '**/help** - get a list of my commands', + 0, +); + +// Catch-all — deliberately NOT using the `g` flag. `RegExp.prototype.test` +// with a `g` regex is stateful (lastIndex advances between calls), which +// caused this handler to silently drop the second-and-later messages the +// framework tested it against. +framework.hears( + /.+/, + (bot, trigger) => { + logger.debug('Unknown message:', trigger.message?.text); + bot.say(`Sorry, I don't know how to respond to "${trigger.message.text}"`); + bot.say('markdown', framework.showHelp()); + }, + 'Unknown command handler', + 99999, +); + +// Periodic access-token refresh. The auth module collapses concurrent +// refreshes into a single request so overlapping ticks won't race. +cron.schedule('0 * * * * *', async () => { + try { + if (await isAccessTokenExpiring()) { + await refreshAccessToken(); + } + } catch (error) { + logger.error('Scheduled token refresh failed:', error); + } +}); + +framework + .start() + .then(() => { + startWebSocketServer(); + }) + .catch((error) => { + logger.error('Failed to start framework:', error); + process.exit(1); + }); + +let shuttingDown = false; +async function shutdown(signal) { + if (shuttingDown) return; + shuttingDown = true; + logger.info(`${signal} received. Shutting down...`); + try { + stopWebSocketServer(); + await framework.stop(); + } catch (error) { + logger.error('Error during shutdown:', error); + } finally { + process.exit(0); + } +} + +process.on('SIGINT', () => shutdown('SIGINT')); +process.on('SIGTERM', () => shutdown('SIGTERM')); diff --git a/src/integrations/google.js b/src/integrations/google.js new file mode 100644 index 0000000..6972ece --- /dev/null +++ b/src/integrations/google.js @@ -0,0 +1,52 @@ +import { config } from '../config.js'; +import { requestJson } from '../http.js'; + +/** + * Google Address Validation API. Returns the raw response body. + */ +export async function validateAddress(street, city, state, postalCode, country) { + const body = { + address: { + regionCode: country, + locality: city, + addressLines: [street], + administrativeArea: state, + postalCode, + }, + }; + const url = `https://addressvalidation.googleapis.com/v1:validateAddress?key=${encodeURIComponent(config.google.apiKey)}`; + return requestJson('POST', url, body); +} + +/** + * Google Time Zone API for a given lat/lon at "now". + */ +export async function getTimeZone(latitude, longitude) { + const timestamp = Math.floor(Date.now() / 1000); + const url = + `https://maps.googleapis.com/maps/api/timezone/json?location=${latitude}%2C${longitude}` + + `×tamp=${timestamp}&key=${encodeURIComponent(config.google.apiKey)}`; + return requestJson('POST', url); +} + +/** + * Reduce a Google addressComponents array to a flat "num street, city, state zip" string. + */ +export function formatE911Address(addressData) { + const parts = {}; + for (const component of addressData.result.address.addressComponents ?? []) { + parts[component.componentType] = component.componentName?.text ?? ''; + } + return `${parts.street_number ?? ''} ${parts.route ?? ''}, ${parts.locality ?? ''}, ${ + parts.administrative_area_level_1 ?? '' + } ${parts.postal_code ?? ''}`.trim(); +} + +export function formatSuite(addressData) { + for (const component of addressData.result.address.addressComponents ?? []) { + if (component.componentType === 'subpremise') { + return component.componentName?.text ?? ''; + } + } + return ''; +} diff --git a/src/integrations/siw.js b/src/integrations/siw.js new file mode 100644 index 0000000..6fbe092 --- /dev/null +++ b/src/integrations/siw.js @@ -0,0 +1,120 @@ +import { config } from '../config.js'; +import { proxyRequest } from '../services/websocket.js'; +import { TIMEZONE_ALIASES } from '../constants.js'; +import { validateAddress, getTimeZone } from './google.js'; +import { validatePhoneNumber } from './twilio.js'; + +function siwAuthHeaders() { + const auth = Buffer.from(`${config.siw.userName}:${config.siw.password}`).toString('base64'); + return { Authorization: `Basic ${auth}` }; +} + +function absoluteUrl(urlOrPath) { + if (urlOrPath.startsWith('http')) return urlOrPath; + const path = urlOrPath.startsWith('/') ? urlOrPath : `/${urlOrPath}`; + return `${config.siw.baseUrl}${path}`; +} + +/** + * Fetch data from SIW via the on-prem remote agent. Accepts a full URL or a + * path (combined with config.siw.baseUrl). Returns the parsed response body. + * + * Throws when the agent isn't connected — SIW is a hard dependency for the + * provisioning flows, so silent fallback would be misleading. + * + * `insecure: true` tells the remote agent to skip TLS verification for this + * specific request. SIW is served with an internal-CA cert that Node's + * default trust store doesn't know about; the agent is inside the + * corporate network reaching an internal-only host, so this is a scoped + * bypass rather than the process-wide NODE_TLS_REJECT_UNAUTHORIZED=0 that + * the original monolith used. + */ +export async function getSIWData(urlOrPath) { + const response = await proxyRequest({ + method: 'GET', + url: absoluteUrl(urlOrPath), + headers: siwAuthHeaders(), + insecure: true, + }); + return response?.data; +} + +function normalizeTimeZone(timeZoneId) { + return TIMEZONE_ALIASES[timeZoneId] ?? timeZoneId; +} + +function joinAddressLines(storeLocation) { + const parts = [ + storeLocation.address, + storeLocation.address2, + storeLocation.address3, + storeLocation.address4, + ] + .map((s) => (typeof s === 'string' ? s.trim() : '')) + .filter(Boolean); + return parts.join(', '); +} + +/** + * Aggregate SIW/Twilio/Google data into the storeInfo object used by every + * provisioning flow. Mirrors the original getStoreInfo() from index.js but + * routed through the remote agent for SIW calls. + */ +export async function getStoreInfo(storeNumber) { + const padded = String(storeNumber).padStart(4, '0'); + const [general, location] = await Promise.all([ + getSIWData(`/api/StoreGeneral/${storeNumber}`), + getSIWData(`/api/StoreLocation/${storeNumber}`), + ]); + + if (!general || !location) { + throw new Error(`SIW returned no data for store ${storeNumber}.`); + } + + const storeInfo = { + mallName: location.name, + name: `Store ${padded}`, + firstName: 'Store', + lastName: padded, + storeNumber: general.store_number, + brand: general.pimary_brand_name, + status: general.store_status_name, + extension: `5${padded}`, + vpExtension: `4${padded}`, + preferredLanguage: 'en_us', + announcementLanguage: 'en_us', + }; + + const twilioLookup = await validatePhoneNumber(location.phone); + storeInfo.phoneNumber = twilioLookup.phone_number; + + const validated = await validateAddress( + joinAddressLines(location), + location.city, + location.state, + location.postal_code, + location.country_code, + ); + + storeInfo.address = { + address1: validated.result.address.formattedAddress, + city: validated.result.address.postalAddress.locality, + state: validated.result.address.postalAddress.administrativeArea, + postalCode: validated.result.address.postalAddress.postalCode, + country: validated.result.address.postalAddress.regionCode, + }; + + if (storeInfo.address.country === 'MX') { + storeInfo.preferredLanguage = 'es_es'; + storeInfo.announcementLanguage = 'es_es'; + storeInfo.phoneNumber = storeInfo.phoneNumber.replace('+1', '+52'); + } + + storeInfo.latitude = validated.result.geocode.location.latitude; + storeInfo.longitude = validated.result.geocode.location.longitude; + + const tz = await getTimeZone(storeInfo.latitude, storeInfo.longitude); + storeInfo.timeZone = normalizeTimeZone(tz.timeZoneId); + + return storeInfo; +} diff --git a/src/integrations/twilio.js b/src/integrations/twilio.js new file mode 100644 index 0000000..8a25e65 --- /dev/null +++ b/src/integrations/twilio.js @@ -0,0 +1,18 @@ +import { config } from '../config.js'; +import { requestJson } from '../http.js'; + +function twilioHeaders() { + const auth = Buffer.from(`${config.twilio.accountSid}:${config.twilio.authToken}`).toString( + 'base64', + ); + return { Authorization: `Basic ${auth}` }; +} + +/** + * Look up a phone number via Twilio's Lookup v2. Returns the raw response + * body; callers typically use `.phone_number` (E.164 normalized). + */ +export async function validatePhoneNumber(phoneNumber) { + const url = `https://lookups.twilio.com/v2/PhoneNumbers/${encodeURIComponent(phoneNumber)}`; + return requestJson('GET', url, undefined, { headers: twilioHeaders() }); +} diff --git a/src/logger.js b/src/logger.js new file mode 100644 index 0000000..83ab77b --- /dev/null +++ b/src/logger.js @@ -0,0 +1,25 @@ +const LEVELS = { debug: 10, info: 20, warn: 30, error: 40 }; + +function currentLevel() { + const raw = (process.env.LOG_LEVEL ?? 'info').toLowerCase(); + return LEVELS[raw] ?? LEVELS.info; +} + +function timestamp() { + return new Date().toISOString(); +} + +function log(level, ...args) { + if (LEVELS[level] < currentLevel()) return; + const stream = level === 'error' || level === 'warn' ? console.error : console.log; + stream(`[${timestamp()}] [${level.toUpperCase()}]`, ...args); +} + +export const logger = { + debug: (...a) => log('debug', ...a), + info: (...a) => log('info', ...a), + warn: (...a) => log('warn', ...a), + error: (...a) => log('error', ...a), +}; + +export default logger; diff --git a/src/services/websocket.js b/src/services/websocket.js new file mode 100644 index 0000000..bcf8567 --- /dev/null +++ b/src/services/websocket.js @@ -0,0 +1,218 @@ +import { WebSocketServer, WebSocket } from 'ws'; +import { config } from '../config.js'; +import { logger } from '../logger.js'; + +/** + * Server side of the on-prem-agent WebSocket bridge. Symmetric to the client + * agent in the netanalyzer project (remoteAgent.js) — the same binary can be + * pointed at this server by setting WS_URL/WS_TOKEN accordingly. + * + * The bot process listens on WS_PORT, one remote agent is allowed to be + * connected at a time, and callers use `proxyRequest({method, url, headers, + * auth, body})` which returns a Promise resolving to the agent's response. + */ + +const PROXY_REQUEST_TIMEOUT_MS = 45000; +const PING_INTERVAL_MS = 30000; +const MAX_PENDING_REQUESTS = 200; + +let wss = null; +let connectedAgent = null; +let pingInterval = null; +const pendingRequests = new Map(); + +function extractToken(req) { + const auth = req.headers['authorization']; + if (auth && /^Bearer\s+/i.test(auth)) { + return auth.replace(/^Bearer\s+/i, '').trim(); + } + try { + const url = new URL(req.url, `http://${req.headers.host || 'localhost'}`); + return url.searchParams.get('token'); + } catch { + return null; + } +} + +function rejectPending(reason) { + for (const { reject, timeout } of pendingRequests.values()) { + clearTimeout(timeout); + reject(new Error(reason)); + } + pendingRequests.clear(); +} + +function handleAgentMessage(data) { + let response; + try { + response = JSON.parse(data); + } catch (error) { + logger.error('Failed to parse agent message:', error.message); + return; + } + + const { requestId } = response; + if (!requestId || !pendingRequests.has(requestId)) { + logger.warn('Received response with unknown requestId:', requestId); + return; + } + + const { resolve, reject, timeout } = pendingRequests.get(requestId); + clearTimeout(timeout); + pendingRequests.delete(requestId); + + if (response.error) { + const err = new Error(response.error); + err.status = response.status; + err.data = response.data; + reject(err); + } else { + resolve(response); + } +} + +export function startWebSocketServer() { + if (wss) return wss; + + wss = new WebSocketServer({ port: config.ws.port }); + + wss.on('error', (err) => { + logger.error('WebSocket server error:', err.message); + }); + + wss.on('connection', (ws, req) => { + const token = extractToken(req); + const expected = config.ws.token; + const remote = req.socket.remoteAddress; + + if (!expected) { + logger.error('WS_TOKEN not configured; refusing connection', { remote }); + ws.close(1011, 'Server misconfigured'); + return; + } + if (!token || token !== expected) { + logger.warn('Rejected agent connection: token mismatch', { + remote, + tokenPresent: !!token, + }); + ws.close(1008, 'Invalid or missing token'); + return; + } + + if (connectedAgent && connectedAgent.readyState === WebSocket.OPEN) { + logger.warn('Replacing previously connected remote agent', { remote }); + try { + connectedAgent.close(1013, 'Replaced by newer agent'); + } catch { + // ignore + } + rejectPending('Remote agent replaced; in-flight requests dropped'); + } + + logger.info('Remote agent connected', { remote }); + connectedAgent = ws; + ws.isAlive = true; + + ws.on('message', handleAgentMessage); + ws.on('pong', () => { + ws.isAlive = true; + }); + ws.on('error', (err) => { + logger.error('Remote agent socket error:', err.message); + }); + ws.on('close', (code, reason) => { + logger.info('Remote agent disconnected', { + code, + reason: reason?.toString() || 'none', + }); + if (connectedAgent === ws) { + connectedAgent = null; + rejectPending('Remote agent disconnected'); + } + }); + }); + + pingInterval = setInterval(() => { + wss.clients.forEach((ws) => { + if (ws.isAlive === false) return ws.terminate(); + ws.isAlive = false; + ws.ping(); + }); + }, PING_INTERVAL_MS); + + logger.info(`WebSocket server listening on port ${config.ws.port}`); + return wss; +} + +export function stopWebSocketServer() { + if (pingInterval) { + clearInterval(pingInterval); + pingInterval = null; + } + if (connectedAgent) { + try { + connectedAgent.close(); + } catch { + // ignore + } + connectedAgent = null; + } + if (wss) { + logger.info('Shutting down WebSocket server'); + wss.close(() => logger.info('WebSocket server closed')); + wss = null; + } + rejectPending('Server shutting down'); +} + +export function isAgentConnected() { + return !!connectedAgent && connectedAgent.readyState === WebSocket.OPEN; +} + +export class AgentNotConnectedError extends Error { + constructor(message = 'No remote SIW agent connected') { + super(message); + this.name = 'AgentNotConnectedError'; + this.code = 'AGENT_NOT_CONNECTED'; + } +} + +/** + * Ask the connected remote agent to perform an HTTP request on our behalf. + * Resolves with `{status, data, headers}` from the agent, rejects with a + * regular Error (with `.status` when the agent proxied a non-2xx) on failure. + */ +export function proxyRequest(requestConfig) { + return new Promise((resolve, reject) => { + if (!isAgentConnected()) { + reject(new AgentNotConnectedError()); + return; + } + if (pendingRequests.size >= MAX_PENDING_REQUESTS) { + reject(new Error('Too many in-flight proxy requests')); + return; + } + + const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2)}`; + const timeout = setTimeout(() => { + pendingRequests.delete(requestId); + reject(new Error(`Proxy request timeout after ${PROXY_REQUEST_TIMEOUT_MS / 1000}s`)); + }, PROXY_REQUEST_TIMEOUT_MS); + + pendingRequests.set(requestId, { resolve, reject, timeout }); + + const payload = JSON.stringify({ + action: 'proxyRequest', + requestId, + ...requestConfig, + }); + + connectedAgent.send(payload, (err) => { + if (err) { + clearTimeout(timeout); + pendingRequests.delete(requestId); + reject(err); + } + }); + }); +} diff --git a/src/webex/announcements.js b/src/webex/announcements.js new file mode 100644 index 0000000..92138bc --- /dev/null +++ b/src/webex/announcements.js @@ -0,0 +1,38 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { webexFetch, webexJson } from './client.js'; +import { config } from '../config.js'; + +/** + * Upload a WAV greeting to the given location. Returns the parsed JSON + * response (includes the announcement `id`). + */ +export async function uploadGreeting(location, filePath, fileName) { + const absolute = path.isAbsolute(filePath) + ? filePath + : path.resolve(config.projectRoot, filePath); + const buffer = await fs.readFile(absolute); + const form = new FormData(); + form.append('file', new Blob([buffer], { type: 'audio/wav' }), fileName); + form.append('name', fileName); + + const response = await webexFetch( + `/telephony/config/locations/${encodeURIComponent(location.id)}/announcements`, + { method: 'POST', body: form }, + ); + if (!response.ok) { + const errorText = await response.text().catch(() => ''); + throw new Error( + `Greeting upload failed for ${location.name}: HTTP ${response.status} ${response.statusText} ${errorText}`, + ); + } + return response.json(); +} + +export async function findLocationAnnouncements(location) { + const data = await webexJson( + 'GET', + `/telephony/config/announcements?locationId=${encodeURIComponent(location.id)}`, + ); + return data?.announcements ?? []; +} diff --git a/src/webex/auth.js b/src/webex/auth.js new file mode 100644 index 0000000..785e4c1 --- /dev/null +++ b/src/webex/auth.js @@ -0,0 +1,93 @@ +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { config } from '../config.js'; +import { logger } from '../logger.js'; + +const TOKEN_URL = 'https://webexapis.com/v1/access_token'; + +let cachedTokens = null; +let refreshing = null; + +async function ensureLoaded() { + if (cachedTokens) return cachedTokens; + try { + const raw = await fs.readFile(config.webexService.tokenStorePath, 'utf8'); + cachedTokens = JSON.parse(raw); + } catch (error) { + if (error.code === 'ENOENT') { + throw new Error( + `Webex service-account token store not found at ${config.webexService.tokenStorePath}. ` + + 'Create it with valid access_token, refresh_token, expiresOn (ISO or locale string).', + ); + } + throw error; + } + return cachedTokens; +} + +async function persist() { + if (!cachedTokens) return; + const target = config.webexService.tokenStorePath; + await fs.mkdir(path.dirname(target), { recursive: true }); + await fs.writeFile(target, JSON.stringify(cachedTokens, null, 4)); +} + +/** + * Returns the current service-account access token. Callers should invoke this + * for every request so refreshes are picked up automatically. + */ +export async function getAccessToken() { + const tokens = await ensureLoaded(); + return tokens.token.access_token; +} + +/** + * Returns true when the current access token is within `withinMs` of expiring. + * Defaults to a 2h (7200000ms) window to match the legacy cron behavior. + */ +export async function isAccessTokenExpiring(withinMs = 2 * 60 * 60 * 1000) { + const tokens = await ensureLoaded(); + const expiresOn = new Date(tokens.expiresOn); + return expiresOn.getTime() - Date.now() <= withinMs; +} + +/** + * Refresh the service-account access token using the stored refresh token. + * Concurrent calls collapse into a single in-flight refresh. + */ +export async function refreshAccessToken() { + if (refreshing) return refreshing; + refreshing = (async () => { + const tokens = await ensureLoaded(); + const params = new URLSearchParams({ + grant_type: 'refresh_token', + client_id: config.webexService.clientId, + client_secret: config.webexService.clientSecret, + refresh_token: tokens.token.refresh_token, + }); + + logger.info('Refreshing Webex service-account access token'); + const response = await fetch(TOKEN_URL, { method: 'POST', body: params }); + if (!response.ok) { + const errorText = await response.text().catch(() => ''); + throw new Error( + `Token refresh failed: HTTP ${response.status} ${response.statusText} ${errorText}`, + ); + } + const json = await response.json(); + cachedTokens.token = json; + cachedTokens.refresh_token = json.refresh_token; + cachedTokens.expiresOn = new Date(Date.now() + json.expires_in * 1000).toISOString(); + cachedTokens.refreshBy = new Date( + Date.now() + json.refresh_token_expires_in * 1000, + ).toISOString(); + await persist(); + logger.info( + `Token refreshed. Expires: ${cachedTokens.expiresOn}, refresh by: ${cachedTokens.refreshBy}`, + ); + return cachedTokens; + })().finally(() => { + refreshing = null; + }); + return refreshing; +} diff --git a/src/webex/autoAttendants.js b/src/webex/autoAttendants.js new file mode 100644 index 0000000..141ed00 --- /dev/null +++ b/src/webex/autoAttendants.js @@ -0,0 +1,50 @@ +import { webexJson } from './client.js'; + +/** + * Build the standard store auto-attendant (business hours: transfer to store, + * after hours: default greeting with 0 -> exit). + */ +export async function createStoreAutoAttendant(location, locationInfo) { + const body = { + name: locationInfo.name, + enabled: true, + phoneNumber: locationInfo.phoneNumber, + extension: null, + tollFreeNumber: false, + firstName: locationInfo.firstName, + lastName: locationInfo.lastName, + languageCode: location.preferredLanguage, + businessSchedule: 'All Hours', + extensionDialing: 'ENTERPRISE', + nameDialing: 'ENTERPRISE', + timeZone: location.timeZone, + businessHoursMenu: { + greeting: 'CUSTOM', + extensionEnabled: false, + keyConfigurations: [ + { + key: '1', + description: 'Transfer to Store', + action: 'TRANSFER_WITHOUT_PROMPT', + value: locationInfo.extension, + }, + ], + audioAnnouncementFile: { + id: location.announcementId, + fileName: `${location.name} - announcement.wav`, + mediaFileType: 'WAV', + level: 'LOCATION', + }, + }, + afterHoursMenu: { + greeting: 'DEFAULT', + extensionEnabled: true, + keyConfigurations: [{ key: '0', action: 'EXIT' }], + }, + }; + return webexJson( + 'POST', + `/telephony/config/locations/${encodeURIComponent(location.id)}/autoAttendants`, + body, + ); +} diff --git a/src/webex/client.js b/src/webex/client.js new file mode 100644 index 0000000..e3a0f3b --- /dev/null +++ b/src/webex/client.js @@ -0,0 +1,71 @@ +import { fetchWithRateLimit, requestJson } from '../http.js'; +import { WEBEX_API_BASE } from '../constants.js'; +import { getAccessToken } from './auth.js'; + +function absolute(url) { + return url.startsWith('http') + ? url + : `${WEBEX_API_BASE}${url.startsWith('/') ? '' : '/'}${url}`; +} + +async function authHeaders(extra = {}) { + const token = await getAccessToken(); + return { + Authorization: `Bearer ${token}`, + ...extra, + }; +} + +/** + * Send a JSON request to the Webex API as the service account. Returns the + * parsed JSON body, or undefined for 204 responses. Throws on non-2xx. + */ +export async function webexJson(method, url, body) { + const headers = await authHeaders(); + return requestJson(method, absolute(url), body, { headers }); +} + +/** + * Send a raw request (used for multipart uploads). Returns the fetch Response. + */ +export async function webexFetch(url, options = {}) { + const headers = await authHeaders(options.headers ?? {}); + return fetchWithRateLimit(absolute(url), { ...options, headers }); +} + +/** + * GET a Webex list endpoint that supports RFC-5988 cursor pagination and + * concatenate all pages into a single array. `initialUrl` may be relative. + * `itemsKey` defaults to "items". + */ +export async function webexListAll(initialUrl, { itemsKey = 'items' } = {}) { + const collected = []; + let nextUrl = absolute(initialUrl); + const headers = await authHeaders(); + + while (nextUrl) { + const response = await fetchWithRateLimit(nextUrl, { method: 'GET', headers }); + if (!response.ok) { + const errorText = await response.text().catch(() => ''); + throw new Error( + `HTTP ${response.status} for GET ${nextUrl}${errorText ? `\n${errorText}` : ''}`, + ); + } + const page = await response.json(); + const items = page[itemsKey] ?? []; + collected.push(...items); + + const linkHeader = response.headers.get('link'); + nextUrl = parseNextLink(linkHeader); + } + return collected; +} + +function parseNextLink(linkHeader) { + if (!linkHeader) return null; + for (const part of linkHeader.split(',')) { + const match = part.trim().match(/^<([^>]+)>;\s*rel="?next"?/); + if (match) return match[1]; + } + return null; +} diff --git a/src/webex/devices.js b/src/webex/devices.js new file mode 100644 index 0000000..d3350db --- /dev/null +++ b/src/webex/devices.js @@ -0,0 +1,168 @@ +import { webexJson } from './client.js'; + +const STORE_DEVICE_CUSTOMIZATIONS = { + ata: { + audioCodecPriority: { + selection: 'REGIONAL', + primary: 'G711a', + secondary: 'G711u', + tertiary: 'G729a', + }, + ataDtmfMode: 'STRICT', + ataDtmfMethod: 'AVT', + cdpEnabled: true, + lldpEnabled: true, + qosEnabled: true, + vlan: { enabled: false, value: 1 }, + webAccessEnabled: false, + nightlyResyncEnabled: true, + snmp: { + enabled: false, + trustedIP: '0.0.0.0/0.0.0.0', + getCommunity: 'public', + setCommunity: 'private', + snmpV3Enabled: false, + }, + }, + dect: { + audioCodecPriority: { + selection: 'REGIONAL', + primary: 'G729', + secondary: 'G711a', + tertiary: 'G711u', + }, + cdpEnabled: true, + lldpEnabled: true, + qosEnabled: true, + vlan: { enabled: false, value: 0 }, + webAccessEnabled: true, + nightlyResyncEnabled: true, + }, + mpp: { + pnacEnabled: true, + audioCodecPriority: { + selection: 'REGIONAL', + primary: 'OPUS', + secondary: 'G722', + tertiary: 'G711u', + }, + backlightTimer: 'FIVE_MIN', + background: { image: 'NONE' }, + displayNameFormat: 'PERSON_NUMBER', + cdpEnabled: true, + defaultLoggingLevel: 'STANDARD', + dndServicesEnabled: false, + acd: { enabled: false, displayCallqueueAgentSoftkeys: 'LAST_PAGE' }, + shortInterdigitTimer: 3, + longInterdigitTimer: 5, + lineKeyLabelFormat: 'PERSON_EXTENSION', + lineKeyLEDPattern: 'DEFAULT', + lldpEnabled: true, + mppUserWebAccessEnabled: false, + offHookTimer: 30, + phoneLanguage: 'PERSON_LANGUAGE', + poeMode: 'NORMAL', + qosEnabled: true, + screenTimeout: { enabled: false, value: 300 }, + vlan: { enabled: false, value: 1, pcPort: 1 }, + wifiNetwork: { enabled: false, authenticationMethod: 'NONE' }, + callHistory: 'WEBEX_UNIFIED_CALL_HISTORY', + contacts: 'XSI_DIRECTORY', + webexMeetingsEnabled: false, + usbPorts: { enabled: false, sideUsbEnabled: false, rearUsbEnabled: false }, + volumeSettings: { + ringerVolume: 9, + speakerVolume: 11, + handsetVolume: 10, + headsetVolume: 10, + eHookEnabled: true, + allowEndUserOverrideEnabled: false, + }, + cfExpandedSoftKey: 'ALL_CALL_FORWARDS', + httpProxy: { + mode: 'OFF', + autoDiscoveryEnabled: true, + port: '3128', + authSettingsEnabled: false, + }, + bluetooth: { enabled: false, mode: 'PHONE' }, + passThroughPortEnabled: false, + userPasswordOverrideEnabled: false, + activeCallFocusEnabled: false, + peerFirmwareEnabled: true, + noiseCancellation: { enabled: true, allowEndUserOverrideEnabled: false }, + dialAssistEnabled: true, + callsPerLine: 4, + nightlyResyncEnabled: true, + missedCallNotificationEnabled: true, + softKeyLayout: { + softKeyMenu: { + idleKeyList: + 'guestin|;guestout|;acd_login|;acd_logout|;astate|;redial|;newcall|;cfwd|;recents|;dnd|;unpark|;psk1|;gpickup|;pickup|;dir|4;miss|5;selfview|;messages|;meetings', + offHookKeyList: 'endcall|1;redial|2;dir|3;lcr|4;unpark|5;pickup|6;gpickup|7', + dialingInputKeyList: 'dial|1;cancel|2;delchar|3;left|5;right|6', + progressingKeyList: 'endcall|2', + connectedKeyList: + 'hold;endcall;xfer;conf;xferLx;confLx;bxfer;phold;redial;dir;park;crdstart;crdstop;crdpause;crdresume;adhocparticipants', + connectedVideoKeyList: + 'hold;endcall;xfer;conf;xferLx;confLx;bxfer;phold;redial;dir;park;crdstart;crdstop;crdpause;crdresume;adhocparticipants', + startTransferKeyList: 'endcall|2;xfer|3', + startConferenceKeyList: 'endcall|2;conf|3', + conferencingKeyList: 'endcall;join;crdstart;crdstop;crdpause;crdresume', + releasingKeyList: 'endcall|2', + holdKeyList: 'resume|1;endcall|2;newcall|3;redial|4;dir|5;adhocparticipants', + ringingKeyList: 'answer|1;ignore|2', + sharedActiveKeyList: 'newcall|1;psk1|2;dir|3;back|4', + sharedHeldKeyList: 'resume|1;dir|4', + }, + psk: { psk1: 'fnc=sd;ext=*11;nme=Call Pull' }, + softKeyMenuDefaults: { + idleKeyList: + 'guestin|;guestout|;acd_login|;acd_logout|;astate|;redial|;newcall|;cfwd|;recents|;dnd|;unpark|;psk1|;gpickup|;pickup|;dir|4;miss|5;selfview|;messages', + offHookKeyList: 'endcall|1;redial|2;dir|3;lcr|4;unpark|5;pickup|6;gpickup|7', + dialingInputKeyList: 'dial|1;cancel|2;delchar|3;left|5;right|6', + progressingKeyList: 'endcall|2', + connectedKeyList: + 'hold;endcall;xfer;conf;xferLx;confLx;bxfer;phold;redial;dir;park;crdstart;crdstop;crdpause;crdresume', + connectedVideoKeyList: + 'hold;endcall;xfer;conf;xferLx;confLx;bxfer;phold;redial;dir;park;crdstart;crdstop;crdpause;crdresume', + startTransferKeyList: 'endcall|2;xfer|3', + startConferenceKeyList: 'endcall|2;conf|3', + conferencingKeyList: 'endcall;join;crdstart;crdstop;crdpause;crdresume', + releasingKeyList: 'endcall|2', + holdKeyList: 'resume|1;endcall|2;newcall|3;redial|4;dir|5', + ringingKeyList: 'answer|1;ignore|2', + sharedActiveKeyList: 'newcall|1;psk1|2;dir|3;back|4', + sharedHeldKeyList: 'resume|1;dir|4', + }, + pskDefaults: { psk1: 'fnc=sd;ext=*11;nme=Call Pull' }, + }, + backgroundImage8875: 'VIOLET_DARK', + backlightTimer68XX78XX: 'ALWAYS_ON', + voiceFeedbackAccessibilityEnabled: true, + }, + wifi: { + audioCodecPriority: { + selection: 'REGIONAL', + primary: 'OPUS', + secondary: 'G722', + tertiary: 'G711u', + }, + ldap: {}, + webAccess: { enabled: true }, + }, +}; + +export async function scheduleStoreDeviceSettings(location) { + const body = { + locationId: location.id, + locationCustomizationsEnabled: true, + customizations: STORE_DEVICE_CUSTOMIZATIONS, + customEnabled: true, + }; + return webexJson('POST', '/telephony/config/jobs/devices/callDeviceSettings', body); +} + +export async function getWebexDeviceDetail(deviceId) { + return webexJson('GET', `/devices/${encodeURIComponent(deviceId)}`); +} diff --git a/src/webex/licensing.js b/src/webex/licensing.js new file mode 100644 index 0000000..a511bcc --- /dev/null +++ b/src/webex/licensing.js @@ -0,0 +1,38 @@ +import { webexJson } from './client.js'; +import { LICENSES, MEETING_SITES } from '../constants.js'; + +/** + * Attach the store-calling license to a user at a given location + extension + * and enroll them in the standard meeting sites. + */ +export async function addWebexCallingToStoreUser(location, user, extension) { + const operation = { + personId: user.id, + licenses: [ + { + id: LICENSES.STORE_CALLING, + operation: 'add', + properties: { locationId: location.id, extension }, + }, + ], + siteUrls: MEETING_SITES, + }; + return webexJson('PATCH', '/licenses/users', operation); +} + +/** + * Clean up legacy trial/preview licenses for a store user, ensure the + * canonical meeting site is set, and add the current store meetings license. + */ +export async function normalizeStoreUserLicenses(user) { + const licenses = [ + ...LICENSES.LEGACY_TO_REMOVE.map((id) => ({ id, operation: 'remove' })), + { id: LICENSES.STORE_MEETINGS_ADD, operation: 'add' }, + ]; + const operation = { + personId: user.id, + licenses, + siteUrls: MEETING_SITES, + }; + return webexJson('PATCH', '/licenses/users', operation); +} diff --git a/src/webex/locations.js b/src/webex/locations.js new file mode 100644 index 0000000..c90433d --- /dev/null +++ b/src/webex/locations.js @@ -0,0 +1,164 @@ +import { webexJson } from './client.js'; +import { + CALLER_ID, + MUSIC_ON_HOLD, + OUTGOING_CALLING_PERMISSIONS, + ROUTE_GROUPS, + VOICE_PORTAL_PASSCODE, +} from '../constants.js'; + +function routeGroupFor(location) { + return location.address.country === 'CA' ? ROUTE_GROUPS.CA : ROUTE_GROUPS.US; +} + +export async function findWebexLocation(locationName) { + const url = `/locations?name=${encodeURIComponent(locationName)}`; + const data = await webexJson('GET', url); + return data.items ?? []; +} + +export async function findWebexLocationById(locationId) { + return webexJson('GET', `/locations/${encodeURIComponent(locationId)}`); +} + +export async function getLocationCallingDetails(locationId) { + return webexJson('GET', `/telephony/config/locations/${encodeURIComponent(locationId)}`); +} + +export async function createLocation(locationInfo) { + const body = { + name: locationInfo.name, + timeZone: locationInfo.timeZone, + announcementLanguage: locationInfo.announcementLanguage, + preferredLanguage: locationInfo.preferredLanguage, + address: { + address1: locationInfo.address.address1, + city: locationInfo.address.city, + state: locationInfo.address.state, + postalCode: locationInfo.address.postalCode, + country: locationInfo.address.country, + }, + latitude: locationInfo.latitude, + longitude: locationInfo.longitude, + }; + return webexJson('POST', '/locations', body); +} + +export async function enableLocationForCalling(location) { + const body = { + id: location.id, + name: location.name, + timeZone: location.timeZone, + announcementLanguage: location.preferredLanguage, + preferredLanguage: location.preferredLanguage, + address: location.address, + }; + return webexJson('POST', '/telephony/config/locations', body); +} + +export async function addPhoneNumbersToLocation(location, phoneNumber) { + const body = { phoneNumbers: [phoneNumber], state: 'ACTIVE' }; + return webexJson( + 'POST', + `/telephony/config/locations/${encodeURIComponent(location.id)}/numbers`, + body, + ); +} + +/** + * Point the location at its route group (used before phone numbers exist). + */ +export async function updateLocationRouteGroup(location) { + const routeGroup = routeGroupFor(location); + const body = { + connection: { id: routeGroup.id, type: 'ROUTE_GROUP' }, + }; + return webexJson('PUT', `/telephony/config/locations/${encodeURIComponent(location.id)}`, body); +} + +/** + * Set the location's caller-ID/external-caller-ID after phone numbers exist. + */ +export async function updateLocationCallingIdentity(location, phoneNumber) { + const body = { + callingLineId: { + name: CALLER_ID.externalCallerIdName, + phoneNumber, + }, + externalCallerIdName: phoneNumber.replace('+1', ''), + }; + return webexJson('PUT', `/telephony/config/locations/${encodeURIComponent(location.id)}`, body); +} + +export async function updateInternalDialing(location) { + const routeGroup = routeGroupFor(location); + const body = { + enableUnknownExtensionRoutePolicy: true, + unknownExtensionRouteIdentity: { + id: routeGroup.id, + name: routeGroup.name, + type: 'ROUTE_GROUP', + }, + }; + return webexJson( + 'PUT', + `/telephony/config/locations/${encodeURIComponent(location.id)}/internalDialing`, + body, + ); +} + +export async function updateLocationOutgoingPermission(location) { + const body = { callingPermissions: OUTGOING_CALLING_PERMISSIONS }; + return webexJson( + 'PUT', + `/telephony/config/locations/${encodeURIComponent(location.id)}/outgoingPermission`, + body, + ); +} + +export async function updateMusicOnHold(location) { + const body = { + callHoldEnabled: true, + callParkEnabled: true, + greeting: 'CUSTOM', + audioFile: { + id: MUSIC_ON_HOLD.announcementId, + fileName: MUSIC_ON_HOLD.fileName, + mediaFileType: 'WAV', + level: 'ORGANIZATION', + }, + }; + return webexJson( + 'PUT', + `/telephony/config/locations/${encodeURIComponent(location.id)}/musicOnHold`, + body, + ); +} + +export async function updateLocationVoicemail(location) { + const body = { voicemailTranscriptionEnabled: false }; + return webexJson( + 'PUT', + `/telephony/config/locations/${encodeURIComponent(location.id)}/voicemail`, + body, + ); +} + +export async function updateLocationVoicePortal(location, vpExtension) { + const body = { + name: `VM - ${location.name}`, + languageCode: location.preferredLanguage, + extension: vpExtension, + firstName: 'VM', + lastName: location.name, + passcode: { + newPasscode: VOICE_PORTAL_PASSCODE, + confirmPasscode: VOICE_PORTAL_PASSCODE, + }, + }; + return webexJson( + 'PUT', + `/telephony/config/locations/${encodeURIComponent(location.id)}/voicePortal`, + body, + ); +} diff --git a/src/webex/schedules.js b/src/webex/schedules.js new file mode 100644 index 0000000..5ad0d76 --- /dev/null +++ b/src/webex/schedules.js @@ -0,0 +1,46 @@ +import { webexJson } from './client.js'; + +const DAYS = [ + { name: 'Sunday', startDate: '2023-06-04', flag: 'sunday' }, + { name: 'Monday', startDate: '2023-06-05', flag: 'monday' }, + { name: 'Tuesday', startDate: '2023-06-06', flag: 'tuesday' }, + { name: 'Wednesday', startDate: '2023-06-07', flag: 'wednesday' }, + { name: 'Thursday', startDate: '2023-06-01', flag: 'thursday' }, + { name: 'Friday', startDate: '2023-06-02', flag: 'friday' }, + { name: 'Saturday', startDate: '2023-06-03', flag: 'saturday' }, +]; + +function weeklyEvent({ name, startDate, flag }) { + const recurWeekly = { + sunday: false, + monday: false, + tuesday: false, + wednesday: false, + thursday: false, + friday: false, + saturday: false, + [flag]: true, + }; + return { + name, + startDate, + endDate: startDate, + startTime: '00:00', + endTime: '23:59', + allDayEnabled: false, + recurrence: { recurForEver: true, recurWeekly }, + }; +} + +export async function createAllHoursSchedule(location) { + const body = { + name: 'All Hours', + type: 'businessHours', + events: DAYS.map(weeklyEvent), + }; + return webexJson( + 'POST', + `/telephony/config/locations/${encodeURIComponent(location.id)}/schedules`, + body, + ); +} diff --git a/src/webex/users.js b/src/webex/users.js new file mode 100644 index 0000000..350de3e --- /dev/null +++ b/src/webex/users.js @@ -0,0 +1,106 @@ +import { webexJson, webexListAll } from './client.js'; + +export async function findWebexUser(email) { + const url = `/people?email=${encodeURIComponent(email)}&callingData=true`; + const data = await webexJson('GET', url); + if (!data?.items || data.items.length !== 1) { + throw new Error(`Found ${data?.items?.length ?? 0} users for ${email}, expected 1.`); + } + return data.items[0]; +} + +export async function findWebexUserPhones(userId) { + return webexJson('GET', `/devices?personId=${encodeURIComponent(userId)}`); +} + +export async function getWebexDeviceDetail(deviceId) { + return webexJson('GET', `/devices/${encodeURIComponent(deviceId)}`); +} + +export async function getAllUsers() { + return webexListAll('/people?callingData=false&max=1000'); +} + +export async function getWebexLicenses() { + const data = await webexJson('GET', '/licenses'); + return data.items; +} + +/** + * Legacy user-update flow used by the display-name fix cron. Preserves the + * exact payload the old code sent. + */ +export async function updateWebexUser(user) { + const body = { + displayName: `${user.firstName} ${user.lastName}`, + licenses: user.licenses, + loginEnabled: true, + }; + return webexJson('PUT', `/people/${encodeURIComponent(user.id)}`, body); +} + +export async function updateUserExtension(user, extension) { + const body = { + extension, + displayName: user.displayName, + licenses: user.licenses, + }; + return webexJson('PUT', `/people/${encodeURIComponent(user.id)}?callingData=true`, body); +} + +export async function updateUserCallExperience(user) { + const body = { + ringDevicesForClickToDialCallsEnabled: false, + ringDevicesForGroupPageEnabled: false, + ringDevicesForCallParkEnabled: false, + browserClientEnabled: false, + desktopClientEnabled: false, + tabletClientEnabled: false, + mobileClientEnabled: false, + }; + return webexJson('PUT', `/people/${encodeURIComponent(user.id)}/features/applications`, body); +} + +export async function updateUserCallerId(user, extension, phoneNumber, options) { + const body = { + types: ['LOCATION_NUMBER', 'CUSTOM'], + selected: 'LOCATION_NUMBER', + extensionNumber: extension, + locationNumber: options.locationFallbackNumber, + tollFreeLocationNumber: false, + firstName: user.firstName, + lastName: user.lastName, + blockInForwardCallsEnabled: false, + externalCallerIdNamePolicy: 'OTHER', + customExternalCallerIdName: options.customExternalCallerIdName, + locationExternalCallerIdName: phoneNumber.replace('+1', ''), + }; + return webexJson('PUT', `/people/${encodeURIComponent(user.id)}/features/callerId`, body); +} + +export async function updateUserVoicemailSettings(user) { + const body = { + enabled: true, + sendAllCalls: { enabled: false }, + sendBusyCalls: { enabled: false, greeting: 'DEFAULT', greetingUploaded: false }, + sendUnansweredCalls: { + enabled: false, + greeting: 'DEFAULT', + greetingUploaded: false, + numberOfRings: 3, + systemMaxNumberOfRings: 20, + }, + notifications: { enabled: false }, + transferToNumber: { enabled: false }, + emailCopyOfMessage: { enabled: false }, + messageStorage: { mwiEnabled: true, storageType: 'INTERNAL' }, + faxMessage: { enabled: false }, + voiceMessageForwardingEnabled: true, + }; + return webexJson('PUT', `/people/${encodeURIComponent(user.id)}/features/voicemail`, body); +} + +export async function setDefaultMeetingSite(userEmail, siteUrl) { + const url = `/meetingPreferences/sites?defaultSite=true&userEmail=${encodeURIComponent(userEmail)}`; + return webexJson('PUT', url, { siteUrl }); +}